openapi: 3.0.1
info:
  title: Reference
  version: 1.8.4
  description: |
    ## Reference

    Lookup tables, in one place. Nothing here is a tutorial — if you are
    integrating for the first time, start with the **Accept Payments** tab
    and come back here when you need to check a value.

    | Looking for | Section |
    |---|---|
    | What a status value means | [Status Codes](#WELPAY_TAB_SLUG/description/status-codes) |
    | Which `PaymentId` to send | [Payment Method IDs](#WELPAY_TAB_SLUG/description/payment-method-ids) |
    | What an error message means | [Error Messages](#WELPAY_TAB_SLUG/description/error-messages) |
    | How fast I may call the API | [Rate Limits](#WELPAY_TAB_SLUG/description/rate-limits) |
    | Smallest and largest amounts | [Transaction Limits](#WELPAY_TAB_SLUG/description/transaction-limits) |
    | What a word means | [Glossary](#WELPAY_TAB_SLUG/description/glossary) |

    ## Status Codes

    The callback and the enquiry endpoint report the same payment states
    using **different values**. This catches people out, so both are shown
    side by side.

    | Status (callback) | Status (enquiry) | Meaning | What you should do |
    |---|---|---|---|
    | `1` | `00` | **Success** — the customer paid and the payment is confirmed. | Fulfil the order. This is your green light to deliver. |
    | other | `Payment pending` | **Pending** — the payment started but has not finished (the customer may still be completing it). | Do not deliver yet. Wait for the next callback, or poll `/enquiry.asp`. |
    | other | `Payment failed` | **Failed** — the payment was declined, or the time limit (TTL) expired. | Let the customer try again with a **new** `RefNo`. |
    | other | `Payment refunded` | **Refunded** — a previously successful payment was refunded. | Reverse the order and notify the customer. |

    > **Never deliver on "pending".** A payment can stay pending for a while.
    > Only `1` / `00` means the money is confirmed. If a payment is still
    > pending past its TTL, check `/enquiry.asp` for the final result — some
    > banks can still complete a payment after its time limit.

    > **Note on success values:** the BackendURL callback uses `1` for a
    > successful payment, while `/enquiry.asp` uses `00` for success. Both mean
    > the payment succeeded — they are separate APIs with separate status
    > encodings.

    <div class="welpay-extras">

    ### Transfer and Payout Statuses

    | Status | Meaning | What you should do |
    |---|---|---|
    | **PENDING** | Transfer created and waiting for your confirmation. Nothing has been sent to the bank yet, and no money has left your balance. | Review the details, then **confirm** to send it, or **cancel** if it is wrong. |
    | **PROCESSING** | You confirmed it (or it is a payout that auto-confirmed). It is now with the bank and the money is moving. | Wait for the final result. You will receive a webhook when it finishes. |
    | **COMPLETED** | The bank paid the recipient successfully. | Reconcile it. The amount and fee have left your available balance. |
    | **FAILED** | The bank could not pay the recipient (for example, a name mismatch or an invalid account number). | Read the failure reason in the webhook, fix the cause, and create a **new** transfer. |
    | **CANCELLED** | Cancelled by you, or automatically after 24 hours in PENDING or PROCESSING. | No money moved. Create a new transfer if you still need to send it. |

    > **`COMPLETED` vs `SUCCESS`:** in callbacks, and in enquiry with
    > `resend=true`, you will see **SUCCESS**. In enquiry with `resend=false`
    > you will see **COMPLETED**. They mean the same thing — the transfer
    > succeeded.

    </div>

    ## Payment Method IDs

    | PaymentId | Payment Method | Default TTL |
    |-----------|---------------|-------------|
    | **83** | **PromptPay QR** - Thailand's standard QR, works with every Thai banking app | 15 minutes |

    `83` is the one to use. Leaving `PaymentId` empty is also valid: your
    customer then picks a method on the payment page, which requires
    `ContentMode=1`.

    <details>
    <summary><strong>Legacy payment method IDs</strong></summary>

    These remain supported for merchants already integrated against them.
    **Do not use them for new integrations** - `83` covers the same ground
    and is not tied to a single provider.

    | PaymentId | Payment Method | Default TTL |
    |-----------|---------------|-------------|
    | 2 | Credit/Debit Card | 30 minutes |
    | 10 | TrueMoney Wallet | 15 minutes |
    | 87 | Bank-specific QR route | 15 minutes |
    | 88 | Bank-specific QR route | 15 minutes |
    | 90 | Bank-specific QR route | 15 minutes |
    | 113 | Bank-specific QR route | 15 minutes |
    | 114 | Bank-specific QR route | 15 minutes |

    Whether any of these is active depends on your merchant configuration.
    Check with Welpay support before relying on one.

    </details>

    **Note:** The payment methods available to you depend on your merchant
    setup. Contact Welpay support to confirm which methods are enabled.

    ## Error Messages

    Returned by `/entry.asp` and in the `ErrDesc` callback field.

    | Error message | What it means |
    |---------------|---------------|
    | Duplicate reference number | Each transaction needs a unique reference number. Use a new one. |
    | Invalid merchant | The merchant code does not exist. Double-check your MerchantCode. |
    | Invalid parameters | Some parameters sent to Welpay are invalid or empty. Review your request. |
    | Overlimit per transaction | The transaction amount exceeds the allowed limit. Adjust the amount. |
    | Payment not allowed | The payment method you requested is not enabled for this merchant code. We can help enable it; please contact Welpay support. |
    | Permission not allow | The registered request URL for your Welpay account does not match, or your request is missing the registered Referer header or comes from an IP that is not allow-listed. Register your request and response URLs and your server IPs with Welpay support. |
    | Signature not match | The signature parameter is incorrect. Verify your signature calculation. |
    | Status not approved | The account is currently suspended or inactive. Reach out to us for assistance. |
    | Invalid payer name | Automatic name matching found that the merchant-provided customer name does not match the bank or provider name. Welpay rejects the payment. |
    | Payment expired | The payment reached its time limit. Some banks may still complete it, so always check the final status. |

    ### Enquiry Responses

    | Response | Status | Description | Next Steps |
    |----------|--------|-------------|-----------|
    | `00` | Success | Payment completed successfully | Fulfil the order and mark the transaction as paid |
    | `Invalid parameters` | Error | A required field is missing or invalid | Check MerchantCode, RefNo, and Amount |
    | `Record not found` | Not Found | The transaction doesn't exist | Verify the RefNo is correct and that entry.asp was called |
    | `Incorrect amount` | Error | The amount doesn't match the original | Provide the exact amount from your entry.asp request |
    | `Payment failed` | Failed | Payment declined or failed | Gently notify the customer and allow a retry with a new RefNo |
    | `Payment pending` | Pending | Payment not yet completed | Wait and retry, and check whether the TTL expired |
    | `Payment refunded` | Refunded | The payment was refunded | Update the order status and notify the customer |

    ## Rate Limits

    Limits are set **per merchant (`MerchantCode`) and per client IP
    address**, whichever is reached first. These are the defaults; your
    agreement may set different values. Limits apply to both sandbox and
    production, and are **per endpoint**, not pooled.

    | Endpoint | Limit |
    |---|---|
    | `/entry.asp` (start payment) | **100 req/sec** |
    | `/enquiry.asp` (check status) | **10 req/sec** |

    <div class="welpay-extras">

    | Endpoint | Limit |
    |---|---|
    | Each Payout API action | **5 req/sec** |
    | Payout token API | **5 req/sec** (get a JWT once, then reuse it) |

    </div>

    Cross a limit and Welpay answers with **HTTP 429 Too Many Requests**.

    | Header | Meaning |
    |---|---|
    | `X-RateLimit-Limit` | The limit for this endpoint (requests/second) |
    | `X-RateLimit-Remaining` | Calls left in the current second |
    | `X-RateLimit-Reset` | Unix timestamp when the window resets |
    | `Retry-After` | Seconds to wait before retrying |

    On a 429: read `Retry-After` and pause, then back off — 1s, 2s, 4s, 8s —
    adding a small random delay so retries don't all land together. Cap your
    retries. Never retry in a tight loop.

    > Rate limits are not fixed. Tell sales if you expect higher traffic and
    > we'll set the right limits in your agreement.

    ## Transaction Limits

    Limits are set per merchant in your agreement. The numbers below are
    common defaults; your agreed limits may be higher.

    | Pay-in limit | Common value |
    |--------------|---------------|
    | Smallest payment | 10.00 THB |
    | Largest payment | 2,000,000.00 THB |

    <div class="welpay-extras">

    | Transfer or payout limit | Common value |
    |--------------------------|---------------|
    | Smallest amount | 10.00 THB |
    | Largest amount | 699,999.99 THB |
    | Total per month | Set in your agreement |

    > The 699,999.99 THB ceiling is a regulatory threshold, not a Welpay
    > setting. Thai anti-money-laundering law requires an electronic transfer
    > or e-payment of **700,000 THB or more** to be reported to AMLO, so the
    > default ceiling sits one satang below it. Larger amounts are possible
    > but enter the reporting regime and need supporting documentation -
    > arrange them with us in advance.

    </div>

    ## Environments

    | Environment | Base URL | Purpose |
    |-------------|----------|--------|
    | Sandbox | `https://payment-sandbox.welpay.co.th/epayment` | Testing and development |
    | Production | `https://payment.welpay.co.th/epayment` | Live transactions |
    | Staging | - | Welpay-internal development only; not available to partners |

    **Note:** We recommend using separate MerchantCode and MerchantKey for
    each environment.

    <div class="welpay-extras">

    ## Supported Banks

    The full 3-digit bank code table — with per-bank account-number lengths
    and retail/corporate coverage — is in the **Send Money** tab, under
    **Supported Banks**. It is kept in one place so the two copies cannot
    drift apart.

    </div>

    ## Glossary

    | Word | Plain meaning |
    |------|---------------|
    | **API** | How two computers talk directly, with no person in between. |
    | **Balance** | The money you hold with Welpay. |
    | **Business day** | A working day — not weekends or Thai holidays. |
    | **Callback** | An automatic message Welpay sends when an event happens. |
    | **Cut-off** | A daily deadline. Anything after it counts as the next day. |
    | **Dashboard** | Your private web page for payments and reports. |
    | **Go live** | Switching to the real system, with real money. |
    | **ITMX** | The system that moves money between Thai banks. |
    | **KYC** | The "Know Your Customer" checks you pass before you start. |
    | **Money-In** | The flow of money coming in from customers (pay-in). |
    | **Pay-in** | Taking money from a customer. |
    | **Payslip** | A report of the payments settled in a batch. |
    | **PDPA** | Thailand's data protection law. |
    | **PSP** | Payment Service Provider (like Welpay). |
    | **PromptPay** | Thailand's main QR payment system. |
    | **QR code** | The square barcode you scan with a phone to pay. |
    | **Reconciliation** | Checking that each payment matches the bank record. |
    | **Rolling reserve** | Part of your recent payments, held for a set time. |
    | **Sandbox** | A safe test copy of Welpay. No real money. |
    | **Settlement** | Money finally reaching your real bank account. |
    | **T+1 / T+2** | One / two calendar days after the payment day. |
    | **VAT** | Thai sales tax (7%), added to fees. |

    <div class="welpay-extras">

    | Word | Plain meaning |
    |------|---------------|
    | **Agent** | A Welpay staff member who handles a payout by hand. |
    | **Finance approver** | The person who approves transfers for your business. |
    | **Money-Out** | The flow of money leaving your balance (transfers and payouts). |
    | **Two-step approval** | One person requests a payment; another approves it. |
    | **Payout** | A Money-Out to a recipient outside Thailand. |
    | **Transfer** | A Money-Out to a bank inside Thailand. |

    > **Transfer = Thailand** (domestic). **Payout = Passport** (leaves the
    > country). In the API the number matches the extra steps:
    > `transferType = 1` needs **1** extra step (confirm);
    > `transferType = 0` needs **0** (auto-confirms).

    </div>
  contact:
    name: Welpay Support
    email: support@welpay.co.th
  x-logo:
    url: ./img/welpay-logo.png
    altText: Welpay Logo
    backgroundColor: '#FFFFFF'
servers:
  - url: https://payment-sandbox.welpay.co.th/epayment
    description: |-
      Sandbox environment for testing
  - url: https://payment.welpay.co.th/epayment
    description: |-
      Production environment
paths: {}
tags: []
x-tagGroups: []
