> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rc.cleverhub.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Create PayIn

> To be able to successfully create a payment link you would need the following APIs in consideration:
  - **Step 1**: Call the **Get PayIn Methods** API to retrieve available payment methods.
  - **Step 2**: Call the **Create PayIn** with the selected method and sender details.
  - **Step 3**: Redirect the customer to the generated **`payment_link`** to complete the checkout.
  - **Step 4**: In the sandbox environment, use the **Simulate PayIn** API to test payment outcomes.
---



## OpenAPI

````yaml /api/openapi/v3-reference.yaml post /v3/payin_links
openapi: 3.0.2
info:
  title: Multi-currency Gateway
  description: "\n---\n\n## Introduction\n\nThe Multi-currency Gateway APIs have been designed to simplify how merchants manage payments across different currencies and methods. All transactions are processed directly through our gateway, ensuring a seamless experience while minimising the effort required for integration.\n\n👉 **Demo:** [View Demo Website](https://minimoo.cleverpay.store/)\n\n### Key Features\n\n- **Unified API Schema**: Handle multiple currencies through a single, consistent schema.\n- **Multi-Currency Support**: Accept and process payments in multiple currencies seamlessly.\n- **Currency-Aware Payment Methods**: Automatically present the supported payment options based on the transaction currency.\n- **Fast Onboarding**: Minimal setup effort with standardised API requests and responses.\n\n---\n\n## Integrate Multi-currency Gateway APIs into your website\n\n### 1. Payment Method\n\nUse this API to integrate and display all payment methods directly on your website. It’s the fastest option, as you won’t need to build or manage the payment method UI yourself.\n\n![Select payment methods](/img/multi-currency-gateway/select-payment-methods.png)\n\n- **Step 1**\_Call the <a href=\"/api-v3-reference/get-pay-in-methods\" target=\"_blank\"><strong>Get PayIn Methods API</strong></a>\_to retrieve the list of available methods. (You may display this list directly in your UI.)\n- **Step 2**\_Call the\_<a href=\"/api-v3-reference/create-pay-in\" target=\"_blank\"><strong>Create PayIn API</strong></a>\_with the selected\_`payin_method_code`\_from Step 1.\n- **Step 3**\_The customer completes checkout\_on the Hello Clever hosted checkout page.\n- **Step 4** Wait for the webhook notification from Hello Clever and update the transaction status in your system accordingly.\n\n---\n\n### 2. Payment Link (Hello Clever brand)\n\nUse this API to integrate and run your own payment gateway. Use our Payment Link API (Hello Clever branded) to start collecting payments in no time, we’ll handle the rest of the checkout experience for you.\n\n![Payment link Hello Clever domain](/img/multi-currency-gateway/payment-link-hello-clever-domain.png)\n\n- **Step 1** Call the <a href=\"/api-v3-reference/create-pay-in\" target=\"_blank\"><strong>Create PayIn API</strong></a> without the `payin_method_code` field.\n- **Step 2**\_Redirect the customer to the generated\_`payment_url`.\n- **Step 3**\_The customer completes checkout by selecting from\_**all available payment methods**\_on the Hello Clever hosted checkout page.\n- **Step 4** Wait for the webhook notification from Hello Clever and update the transaction status in your system accordingly.\n\n---\n\n### 3. Payment Link (Your brand)\n\nPlease get in touch with [support@helloclever.co](mailto:support@helloclever.co) to customise your brand\n\n![Payment link custom domain](/img/multi-currency-gateway/payment-link-custom-domain.png)\n\n---\n\n## Integrate Multi-currency Gateway APIs with UX Control\n\n### 1. Redirect UX\n\nAfter receiving the `payment_url` from the <a href=\"/api-v3-reference/create-pay-in\" target=\"_blank\"><strong>Create PayIn API</strong></a>, redirect the user to that URL to complete the payment.\n\n**NOTE**: Some browsers (such as Safari, Chrome, etc.) block redirect functionality, preventing automatic redirection to the Payment Link. You need to allow pop-ups in your browser settings [here](#troubleshooting).\n\n**Example**:\n\n![Redirect UX](/img/multi-currency-gateway/redirect-ux.png)\n\n---\n\n### 2. Popup UX\n\nAfter receiving the `payment_url` from the <a href=\"/api-v3-reference/create-pay-in\" target=\"_blank\"><strong>Create PayIn API</strong></a>, render it inside a pop-up window so the user can complete the payment without leaving your site.\n\n**Example**:\n\n![Popup UX](/img/multi-currency-gateway/popup-ux.png)\n\nIn the Popup option, you can control for handling of payment success or failure events for closing the pop-up accordingly. This guide shows you how.\n\n---\n\n### Handle Payment Events in Popup UX\n\n_Listen to payment success or failure events to trigger your logic and close the pop-up when the transaction is completed._\n\n```jsx\nwindow.addEventListener(\"message\", function (event) {\n  if (\n    !event.data?.hc_payment_event ||\n    typeof event.data?.hc_payment_event !== \"object\"\n  )\n    return;\n\n  // Check the event type\n  if (event.data.hc_payment_event.event_type === \"onChange\") {\n    if (event.data.hc_payment_event.page_state === \"success\") {\n      // Handle your logic here\n      // E.g: If you want to redirect the main page to the success URL\n      // window.location.href = event.data.hc_payment_event.redirect_url.success;\n    }\n\n    if (event.data.hc_payment_event.page_state === \"failed\") {\n      // Handle your logic here\n      // E.g: If you want to redirect the main page to the failure URL\n      // window.location.href = event.data.hc_payment_event.redirect_url.failure;\n    }\n  }\n});\n```\n\n**Event data object**\n\n- `event_type`: The type of event triggered by the payment link\n  - `onChange`: Triggered when the payment link state changes. This occurs when the `page_state` is success or failed page, or when the countdown reaches 0.\n  - `onDone` : Triggered when the **Done** button is clicked on the success page; or when the countdown counts to 0.\n    ![Popup Success](/img/multi-currency-gateway/popup-success.png)\n- `page_state`: The current state of the payment link\n  - `success`: when the payment link is on the success page\n  - `failed`: when the payment link is on the failed page\n\n```jsx\n// Data format\nhc_payment_event {\n  event_type: string, // \"onChange\" || \"onDone\"\n  page_state: \"success\" | \"failed\"\n}\n```\n\n**Example:** If you want to control when the pop-up closes on successful or failed transactions.\n\n![Popup Success](/img/multi-currency-gateway/popup-success.png)\n\n**Best Practices**\n  - Treat **webhooks** as the source of truth for payment status.  \n  - Use **event listener** only to improve UX (instant feedback, UI updates).\n\n---\n\n## Troubleshooting\n\n- Some browsers (such as Safari, Chrome, etc.) block redirect functionality, preventing automatic redirection to the Payment Link. You need to allow pop-ups in your browser settings.\n\n  ![Popup Blocked 1](/img/multi-currency-gateway/popup-blocked-1.png)\n\n  ![Popup Blocked 2](/img/multi-currency-gateway/popup-blocked-2.png)\n\n  1. Click Tab icon\n  2. Open “Settings for [DOMAIN]”\n\n     ![Resolve Popup 1](/img/multi-currency-gateway/resolve-popup-1.png)\n\n  3. Allow “Pop-up Window Blocked”\n\n     ![Resolve Popup 2](/img/multi-currency-gateway/resolve-popup-2.png)\n"
  version: 3.0.0
  termsOfService: https://helloclever.co/terms
  contact:
    email: support@helloclever.co
servers:
  - url: https://api.cleverhub.co/api
    description: Sandbox Environment
  - url: https://api-merchant.helloclever.co/api
    description: Production Environment
security:
  - app-id: []
    secret-key: []
paths:
  /v3/payin_links:
    post:
      tags:
        - PayIn
      summary: Create PayIn
      description: >-
        To be able to successfully create a payment link you would need the
        following APIs in consideration:
          - **Step 1**: Call the **Get PayIn Methods** API to retrieve available payment methods.
          - **Step 2**: Call the **Create PayIn** with the selected method and sender details.
          - **Step 3**: Redirect the customer to the generated **`payment_link`** to complete the checkout.
          - **Step 4**: In the sandbox environment, use the **Simulate PayIn** API to test payment outcomes.
        ---
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - amount
                - description
                - sender_info
              properties:
                amount:
                  type: number
                  description: Transaction amount.
                payin_method_code:
                  type: string
                  description: >
                    Specific payin method code to be used for this payment. You
                    will receive this from the Get payment methods API  Optional
                    — if not provided, user will choose from available methods.
                expires_in:
                  type: integer
                  description: >
                    Expiration time of transaction (seconds).   Default: 1800
                    (30 min), Min: 900 (15 min).
                description:
                  type: string
                  description: Description of the payment transaction
                external_id:
                  type: string
                  description: Custom ID.
                redirect_url:
                  type: object
                  properties:
                    success:
                      type: string
                      format: uri
                      description: URL when payment succeeds.
                    failure:
                      type: string
                      format: uri
                      description: URL when payment fails.
                webhook_notification:
                  type: object
                  description: Webhook configuration for transaction status updates
                  properties:
                    endpoint_url:
                      type: string
                      format: uri
                      description: Webhook endpoint URL.
                    authorization_header:
                      type: string
                      description: Authorization header included in webhook callback.
                sender_info:
                  type: object
                  description: Information about the customer.
                  properties:
                    email:
                      type: string
                      format: email
                      description: Customer's email.
                    first_name:
                      type: string
                      description: Customer's first name.
                    last_name:
                      type: string
                      description: Customer's last name.
                    gender:
                      type: string
                      description: Gender of the customer.
                    contact_type:
                      type: string
                      description: Optional contact type.
                    dob:
                      type: string
                      format: date
                      description: Date of birth.
                    reg_no:
                      type: string
                      description: Registration number.
                    state:
                      type: string
                      description: State/Province.
                    user_id:
                      type: string
                      description: User ID from the merchant system.
                    upi_id:
                      type: string
                      description: UPI ID.
                    phone:
                      type: string
                      description: Customer's phone number.
                    country_code:
                      type: string
                      description: ISO 2-letter country code.
                    address:
                      type: string
                      description: Full street address.
                    city:
                      type: string
                      description: City.
                    postal_code:
                      type: string
                      description: Postal/ZIP code.
                    account_name:
                      type: string
                      description: Name of the account to receive payments
                    account_number:
                      type: string
                      description: Mobile money account number.
                    bank_code:
                      type: string
                      description: Bank code for the charge.
                    bank_name:
                      type: string
                      description: Bank name for the charge.
                    document_type:
                      type: string
                      description: Type of document for the charge.
                    document_number:
                      type: string
                      description: Document number for the charge.
                  required:
                    - email
                    - first_name
                    - last_name
                metadata:
                  type: object
                  additionalProperties: true
                  description: Optional custom metadata to attach to the transaction.
                  properties:
                    transliterate:
                      type: boolean
                      default: false
                      example: true
                      description: >
                        Set to `true` to convert the customer's name into the
                        bank's required script before submitting the payment.


                        - Currently supported only for `jp_bank_jpy` — converts
                        `first_name` / `last_name` into full-width Katakana for
                        Japanese bank transfers.

                        - Input must contain only Latin letters (a–z, A–Z,
                        spaces). For reliable conversion, the name should be in
                        **romaji** (romanized Japanese). Latin text that is not
                        valid romaji is accepted but may fail to transliterate.
                        Invalid input returns a validation error.

                        - For other payment methods this flag is ignored.

                        - Example (valid romaji): "Taro Yamada" → "タロウ ヤマダ"
                        (romaji → full-width Katakana).

                        - Example (invalid): "Robert" → "ロベrt" — non-romaji
                        Latin cannot be fully converted, so it is rejected.
            example:
              amount: 100000
              payin_method_code: vn_vietqr_vnd
              expires_in: null
              description: Top-up wallet
              external_id: '123456'
              redirect_url:
                success: https://example.com/success
                failure: https://example.com/failure
              webhook_notification:
                endpoint_url: https://example.com/webhook
                authorization_header: Header 123456789
              sender_info:
                email: email@gmail.com
                first_name: John
                last_name: Doe
                gender: male
                contact_type: individual
                dob: '1990-01-01'
                reg_no: A1234567
                state: Ho Chi Minh
                user_id: user_12345
                upi_id: johndoe@upi
                phone: '0123456789'
                country_code: VN
                address: 123 abc
                city: Ho Chi Minh City
                postal_code: '700000'
                account_name: John Doe
                account_number: '233240000000'
                bank_code: VCB
                document_type: passport
                document_number: P123456789
              metadata:
                custom_note: Priority customer
              create_payment_link_jpy_example:
                amount: 100000
                payin_method_code: jp_bank_jpy
                expires_in: null
                description: Top-up wallet
                external_id: '123456'
                redirect_url:
                  success: https://example.com/success
                  failure: https://example.com/failure
                webhook_notification:
                  endpoint_url: https://example.com/webhook
                  authorization_header: Header 123456789
                sender_info:
                  first_name: John
                  last_name: Doe
                metadata:
                  transliterate: true
      responses:
        '200':
          description: Payin link created successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  uuid:
                    type: string
                    description: Unique identifier for the payment transaction.
                  payment_url:
                    type: string
                    format: uri
                    description: >-
                      URL of the created payment link where the merchant can
                      complete the payment.
                  expires_at:
                    type: string
                    format: date-time
                    description: Expiration time (ISO 8601 UTC) of the payment link
              example:
                uuid: Z2Q3FWBW
                payment_url: https://example.com/ZSxw187
                expires_at: '2025-07-24T16:00:00Z'
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: object
                    properties:
                      code:
                        type: string
                      message:
                        type: string
              example:
                errors:
                  code: REQUIRE_LOGIN
                  message: Not Authorised
        '422':
          description: Unprocessable Entity
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: object
                    properties:
                      message:
                        type: string
              example:
                errors:
                  message: Email is missing in sender information
components:
  securitySchemes:
    app-id:
      type: apiKey
      in: header
      name: app-id
      description: |
        A unique identifier assigned to each application.
    secret-key:
      type: apiKey
      in: header
      name: secret-key
      description: |
        A secure token associated with the `app-id`.

````

## Related topics

- [Create a Payin](/api/payin/create-a-payin.md)
- [Multi-Currency Payin API Reference (v2)](/api/v2/payin.md)
- [Managing Payins in the Merchant Portal](/portal/payins.md)
