NAV undefined
bash

Payments API Introduction

Our new set of Payment APIs allows merchants to integrate to any of our supported money-in payment channels using a consolidated and unified set of APIs. Through these APIs, merchants are able to use the same endpoint for any payment method type in any supported market.

The Payment APIs consist of three main resources:

Supported Channels

E-wallet ๐Ÿ‡ฎ๐Ÿ‡ฉ ๐Ÿ‡ต๐Ÿ‡ญ ๐Ÿ‡ป๐Ÿ‡ณ ๐Ÿ‡ฒ๐Ÿ‡พ

The following channels are supported for payment method type EWALLET. For more information about e-wallet channels, you may visit our docs page.

COUNTRY
CHANNEL NAME
CHANNEL CODE
ONE TIME USE
MULTIPLE USE
REFUND
๐Ÿ‡ฎ๐Ÿ‡ฉ ID DANA DANA โœ… โœ… โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID LinkAja LINKAJA โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID OVO OVO โœ… โœ… โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID ASTRAPAY ASTRAPAY โœ… โŒ โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID JENIUSPAY JENIUSPAY โœ… โŒ โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID ShopeePay SHOPEEPAY โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID NEXCASH NEXCASH โœ… โŒ โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH GrabPay GRABPAY โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH GCash GCASH โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH Maya (PayMaya) PAYMAYA โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH ShopeePay SHOPEEPAY โœ… โœ… โœ…
๐Ÿ‡ป๐Ÿ‡ณ VN Appota APPOTA โœ… โŒ โœ…
๐Ÿ‡ป๐Ÿ‡ณ VN MOMO MOMO โœ… โŒ โœ…
๐Ÿ‡ป๐Ÿ‡ณ VN ZaloPay ZALOPAY โœ… โŒ โœ…
๐Ÿ‡ป๐Ÿ‡ณ VN VNPTWALLET VNPTWALLET โœ… โŒ โœ…
๐Ÿ‡ป๐Ÿ‡ณ VN ShopeePay SHOPEEPAY โœ… โŒ โœ…
๐Ÿ‡ป๐Ÿ‡ณ VN ViettelPay VIETTELPAY โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH WechatPay WECHATPAY โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH LINE Pay LINEPAY โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH ShopeePay SHOPEEPAY โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH TrueMoney TRUEMONEY โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Touch n Go TOUCHNGO โœ… โœ… โœ…
๐Ÿ‡ฒ๐Ÿ‡พ MY ShopeePay SHOPEEPAY โœ… โœ… โœ…
๐Ÿ‡ฒ๐Ÿ‡พ MY GrabPay GRABPAY โœ… โœ… โœ…
๐Ÿ‡ฒ๐Ÿ‡พ MY WechatPay WECHATPAY โœ… โŒ โœ…

Direct Debit ๐Ÿ‡ฒ๐Ÿ‡จ ๐Ÿ‡ต๐Ÿ‡ญ ๐Ÿ‡น๐Ÿ‡ญ ๐Ÿ‡ฒ๐Ÿ‡พ

The following channels are supported for payment method type DIRECT_DEBIT. You may visit our docs page for more information about direct debit channels.

COUNTRY
CHANNEL NAME
CHANNEL CODE
ONE TIME USE
MULTIPLE USE
REFUND
๐Ÿ‡ฒ๐Ÿ‡จ ID BRI BRI โœ… โœ… โœ…
๐Ÿ‡ฒ๐Ÿ‡จ ID MANDIRI MANDIRI โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH BPI BPI โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH RCBC RCBC โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH Unionbank UBP โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH Chinabank CHINABANK โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH BDO EPAY BDO_EPAY โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Siam Commercial Bank SCB โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Krungthai Bank KTB โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Bangkok Bank BBL โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Bank of Ayudhya BAY โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH K-Bank KBANK_MB โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Bank of Ayudhya BAY_MB โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Krungthai Bank KTB_MB โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Siam Commercial Bank SCB_MB โœ… โŒ โŒ
๐Ÿ‡น๐Ÿ‡ญ TH Bangkok Bank BBL_MB โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY AFFIN AFFIN_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY AGRO AGRO_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY ALLIANCE ALLIANCE_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY AMBANK AMBANK_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY ISLAM ISLAM_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY MUAMALAT MUAMALAT_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY BOC BOC_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY RAKYAT RAKYAT_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY BSN BSN_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY CIMB CIMB_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY HLB HLB_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY HSBC HSBC_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY KFH KFH_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY MAYB2E MAYB2E_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY MAYB2U MAYB2U_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY OCBC OCBC_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY PUBLIC PUBLIC_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY RHB RHB_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY SCH SCH_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY UOB UOB_FPX โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Affin Bank B2B AFFIN_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY AGRONetBIZ AGRO_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Alliance Bank (Business) ALLIANCE_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY AmBank AMBANK_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Bank Islam ISLAM_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Bank Muamalat MUAMALAT_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY BNP Paribas BNP_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY CIMB Bank CIMB_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Citibank Corporate Banking CITIBANK_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Deutsche Bank DEUTSCHE_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Hong Leong Bank HLB_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY HSBC Bank HSBC_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY i-bizRAKYAT RAKYAT_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY KFH KFH_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Maybank2E MAYB2E_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY OCBC Bank OCBC_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Public Bank PB enterprise PUBLIC_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY RHB Bank RHB_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY Standard Chartered SCH_FPX_BUSINESS โœ… โŒ โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY UOB Regional UOB_FPX_BUSINESS โœ… โŒ โŒ

Over-the-Counter/Retail Outlet ๐Ÿ‡ฒ๐Ÿ‡จ ๐Ÿ‡ต๐Ÿ‡ญ

The following channels are supported for payment method type OVER_THE_COUNTER. You may visit our docs page for more information about over-the-counter or retail outlet channels.

COUNTRY
CHANNEL NAME
CHANNEL CODE
ONE TIME USE
MULTIPLE USE
REFUND
๐Ÿ‡ฒ๐Ÿ‡จ ID Alfamart ALFAMART โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID Indomaret INDOMARET โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH 7-Eleven via 7-Connect Code 7ELEVEN โœ… โŒ โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH 7-Eleven via CliQQ 7ELEVEN_CLIQQ โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH Cebuana Lhuillier CEBUANA โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH ECPay ECPAY โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH Palawan Express PALAWAN โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH MLhuillier MLHUILLIER โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH ECPay via Dragonloanยน ECPAY_DRAGONLOAN โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH LBC LBC โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH RD_PAWNSHOP RD_PAWNSHOP โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH CVM CVM โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH ECPAY_SCHOOL ECPAY_SCHOOL โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH USSC USSC โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH SM_BILLS SM_BILLS โœ… โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH ROBINSONS_BILLS ROBINSONS_BILLS โœ… โœ… โŒ

Virtual Account ๐Ÿ‡ฒ๐Ÿ‡จ ๐Ÿ‡ป๐Ÿ‡ณ ๐Ÿ‡น๐Ÿ‡ญ ๐Ÿ‡ต๐Ÿ‡ญ ๐Ÿ‡ฒ๐Ÿ‡พ

The following channels are supported for payment method type VIRTUAL_ACCOUNT. For more information about virtual accounts, you may visit our docs page.

COUNTRY
CHANNEL NAME
CHANNEL CODE
ONE TIME USE
MULTIPLE USE
REFUND
๐Ÿ‡ฒ๐Ÿ‡จ ID BCA BCA โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID BJB BJB โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID BNI BNI โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID BRI BRI โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID BSI BSI โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID BSS (BANK SAHABAT SAMPOERNA) BSS (BANK SAHABAT SAMPOERNA) โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID CIMB CIMB โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID MANDIRI MANDIRI โœ… โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡จ ID PERMATA PERMATA โœ… โœ… โŒ
๐Ÿ‡ป๐Ÿ‡ณ VN PV PV โœ… โœ… โŒ
๐Ÿ‡ป๐Ÿ‡ณ VN VIET CAPITAL VIETCAPITAL โœ… โœ… โŒ
๐Ÿ‡ป๐Ÿ‡ณ VN WOORI WOORI โœ… โœ… โŒ
๐Ÿ‡ป๐Ÿ‡ณ VN MSB MSB โœ… โœ… โŒ
๐Ÿ‡ป๐Ÿ‡ณ VN VPB VPB โœ… โœ… โŒ
๐Ÿ‡ป๐Ÿ‡ณ VN BIDV BIDV โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH STANDARD CHARTERED STANDARD_CHARTERED โŒ โœ… โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH INSTAPAY / PESONET BANK_TRANSFER โŒ โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY UOB UOB โŒ โœ… โŒ
๐Ÿ‡ฒ๐Ÿ‡พ MY AMBANK AMBANK โŒ โœ… โŒ

QR Code ๐Ÿ‡ฎ๐Ÿ‡ฉ ๐Ÿ‡น๐Ÿ‡ญ

The following channels are supported for payment method type QR_CODE. You may visit our docs page for more information about QR Code payments.

COUNTRY
CHANNEL NAME
CHANNEL CODE
ONE TIME USE
MULTIPLE USE
REFUND
๐Ÿ‡ฎ๐Ÿ‡ฉ ID DANA (QRIS) DANA โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID Linkaja (QRIS) LINKAJA โœ… โœ… โŒ
๐Ÿ‡น๐Ÿ‡ญ TH PromptPay PROMPTPAY โœ… โŒ โŒ
๐Ÿ‡ต๐Ÿ‡ญ PH QRPH QRPH โœ… โŒ โŒ

Supported Issuers for QR Code Refunds

COUNTRY
ISSUER
FULL AMOUNT (WITHIN 24 HOURS)
FULL AMOUNT (AFTER 24 HOURS)
PARTIAL AMOUNT
๐Ÿ‡ฎ๐Ÿ‡ฉ ID DANA โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID ShopeePay โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID OVO โœ… โœ… โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID LinkAja โœ… โœ… โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID Mandiri โœ… โŒ โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID Permata โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID CIMB โœ… โœ… โŒ
๐Ÿ‡ฎ๐Ÿ‡ฉ ID Jenius / BTPN โœ… โœ… โœ…
๐Ÿ‡ฎ๐Ÿ‡ฉ ID BSI โœ… โœ… โœ…

Card ๐Ÿ‡ฎ๐Ÿ‡ฉ ๐Ÿ‡ต๐Ÿ‡ญ

The following channels are supported for payment method type CARD. You may visit our docs page for more information about Card payments.

Country
Currencies
ONE TIME USE
MULTIPLE USE
REFUND
๐Ÿ‡ฎ๐Ÿ‡ฉ ID Indonesian Rupiah (IDR) โœ… โœ… โœ…
๐Ÿ‡ต๐Ÿ‡ญ PH Philippines Peso (PHP)
United States Dollar (USD)
โœ… โœ… โœ…

Payment Object

Payment object represents the actual funds transaction/attempt made to a payment method. This object will be found through payment webhooks (e.g payment.suceeeded or payment.failed) to give the final status of the trasaction.

Payment Object Example

{
    "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
    "amount": 1000,
    "status": "SUCCEEDED",
    "country": "PH",
    "created": "2022-08-12T13:30:40.9209Z",
    "updated": "2022-08-12T13:30:58.729373Z",
    "currency": "PHP",
    "metadata": {
        "sku": "ABCDEFGH"
    },
    "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
    "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
    "payment_method": {
        "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "ACTIVE",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:40.221525Z",
        "metadata": null,
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                "masked_bank_account_number": "XXXXXX1234"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            }
        },
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "direct_bank_transfer": null
    },
    "description": null,
    "failure_code": null,
    "payment_detail": null,
    "channel_properties": null,
    "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
}
Body Parameter Type Description
id
required
string Unique identifier for the payment. Its prefix varies based on the payment method type.
payment_request_id
nullable
string Unique identifier for the payment request. Prefix will vary according to the payment method used.
reference_id
required
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
customer_id
nullable
string ID of the customer object to which the account token are linked to
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
amount
required
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • VND - Only supports positive integers.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • SUCCEEDED - The payment was successfully completed.
  • FAILED - The payment failed. See failure_code for the specific reason why the transaction failed.
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
channel_properties
nullable
object Specific settings applied to the payment request, overwriting the ones in the Payment Method object.
For multiple use OVO, and SHOPEEPAY (ID & MY):
Key Value
redeem_points
nullable
string Indicates whether or not to use the Payment Method's points_balance in the transaction
Possible values:
  • REDEEM_NONE - No points will be used
  • REDEEM_ALL - points will be used to offset payment amount before cash balance is used.
    REDEEM_ALL can only be used when approved by OVO for promotions.
    For SHOPEEPAY (ID), only up to 50% of the transaction amount (rounded down) can be paid using SHOPEEPAY coins.
Default value: REDEEM_NONE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful

For PAYMAYA:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
nullable
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.

For SHOPEEPAY(VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending

For WECHATPAY (MY):
Key Value
device_type
required
string determines the device type of the end user. Accepts the following values:
  • DESKTOP
  • MOBILE
payer_ip_address
nullable
string The IP address of the end user's client (e.g. 192.168.0.1)
Required if device_type is set to MOBILE
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending
Required if device_type is set to MOBILE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
Required if device_type is set to MOBILE
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization has failed
Required if device_type is set to MOBILE

For BRI Direct Debit:
Key Value
require_auth
nullable
string Toggle used to require end-customer to input undergo OTP validation before completing a payment.
  • true
  • false
Default value: true

For BPI, UBP, RCBC, CHINABANK Direct Debit:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed

For CARD:
Key Value
skip_three_d_secure
required
boolean To indicate whether to perform 3DS on the payment request
Defaults to false
success_return_url
nullable
string URL where the end-customer is redirected if the linking is successful.
Required when skip_three_d_secure = false.
This will be null if not applicable.
failure_return_url
nullable
string URL where the end-customer is redirected if the linking has failed.
Required when skip_three_d_secure = false.
This will be null if not applicable.
merchant_id_tag
nullable
string Tag for the Merchant ID that you want to associate this payment with. This is for merchants using their own MIDs to specify which MID they want to use
cardonfile_type
nullable
string Type of โ€œcredential-on-fileโ€ / โ€œcard-on-fileโ€ / COF payment for subsequent usage. Indicates future card-on-file usage.
If you intend for a card to be used for future COF transactions, then this value must be included so that Xendit can inform the processors of this setup, and then after that on every transaction following the first transaction.
Default: CUSTOMER_UNSCHEDULED
Possible values:
  • CUSTOMER_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments that do not follow a schedule.
    Example: simple โ€œsave card for future checkoutโ€ eCommerce flow, the future payments would always be CUSTOMER_UNSCHEDULED
  • MERCHANT_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments initiated without customer interaction and do not follow a schedule
    Example: auto top-up payment flow
  • RECURRING - If you intend to use this Payment Method to process a series of transactions at fixed, regular intervals.
    Example: Subscriptions

Notes: In order to process MERCHANT_UNSCHEDULED and RECURRING card-on-file transaction types:
  • Aggregator Merchant will need to be allowed to perform transaction without 3DS, please check this guide for self-serve or contact Xendit representative for enabling 3DS as optional
  • Switcher Merchant with their own acquiring bank MID will need to have MID for non 3DS transactions and support recurring configured by the acquirer.

For GRABPAY (MY):
Key Value
allowed_payment_options
nullable
Array of enums
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Usage for each Payment method reusability
  • ONE_TIME_USE - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
  • MULTIPLE_USE - Choose One payment option to use, default will use GrabPay Ewallet balance

payment_detail
nullable
object Additional information provided by that partner channel upon the creation of the payment.
For VIRTUAL_ACCOUNT Payments:
Key Value
network
nullable
string This can be provided by the partner channel to indicate the network used for making the payment. For Philippines multi-use VA payments, this will be "InstaPay" for payments โ‰คP50000, and "PESONet" for payments >P50000.

For OVER_THE_COUNTER Payments:
Key Value
remarks
nullable
string This can be provided by the partner channel for additional information upon payment of the end-customer in the outlet/branch. Will be null if none is provided.

For EWALLET Payments:
Key Value
fund_source
nullable
string The type of the fund origin
SHOPEEPAY ID - EWALLET_BALANCE, 1_MONTH_INSTALLMENT, 2_MONTH_INSTALLMENT, 3_MONTH_INSTALLMENT, 6_MONTH_INSTALLMENT, 12_MONTH_INSTALLMENT
SHOPEEPAY MY - SHOPEEPAY_BALANCE, SPAYLATER_INSTALLMENTS_1MO, SPAYLATER_INSTALLMENTS_2MO, SPAYLATER_INSTALLMENTS_3MO, SPAYLATER_INSTALLMENTS_6MO, SPAYLATER_INSTALLMENTS_12MO
source
nullable
string The name of the channel
SHOPEEPAY ID - Shopeepay

failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
created
required
string ISO 8601 Timestamp for Payment object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment creation.

Payment Request Object

This object will be found in the response of Create Payment Request endpoint. This object will give you the information of the status after the payment request.

Payment Request Object Example

{
    "id": "pr-76aca7a8-da92-4480-b97a-1c44b05d132d",
    "reference_id": "15bafc7c-b5ea-484b-a151-41d60bb1e964",
    "business_id": "5f27a14a9bf05c73dd040bc8",
    "currency": "IDR",
    "amount": 10000,
    "country": "ID",
    "payment_method": {
        "id": "pm-f77e73c7-ade1-45bf-8aa8-bc320124877c",
        "type": "CARD",
        "reference_id": "ed9061ee-0f0e-4086-b6b9-5282a30fadf3",
        "description": "Card Transaction",
        "created": "2022-09-13T02:14:31.096959Z",
        "updated": "2022-09-13T02:14:31.318608Z",
        "card": {
            "currency": "IDR",
            "channel_properties": {
                "skip_three_d_secure": null,
                "success_return_url": "https://your-redirect-website.com/success",
                "failure_return_url": "https://your-redirect-website.com/failure",
                "cardonfile_type": null
            },
            "card_information": {
                "token_id": "8b8b6ff69cf169c534a828fbce61e0a2",
                "masked_card_number": "400000XXXXXX1091",
                "cardholder_name": "Test Person",
                "expiry_month": "10",
                "expiry_year": "2026",
                "fingerprint": "c5fdf4f5e775ac60ced4447857c3e9ef",
                "type": "CREDIT",
                "network": "VISA",
                "country": "ID",
                "issuer": "BRI"
            },
            "card_verification_results": null
        },
        "ewallet": null,
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": {},
        "reusability": "ONE_TIME_USE",
        "status": "ACTIVE"
    },
    "description": null,
    "metadata": null,
    "customer_id": null,
    "created": "2022-09-13T02:14:37.192601423Z",
    "updated": "2022-09-13T02:14:37.192601423Z",
    "status": "PENDING",
    "actions": [],
    "failure_code": null,
    "capture_method": "AUTOMATIC",
    "initiator": "CUSTOMER",
    "card_verification_results": null,
    "channel_properties": {
        "skip_three_d_secure": true
    },
    "shipping_information": null
}



Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
customer
optional
object This object may be used if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
nullable
string Last or family name of customer
nationality
nullable
string Country code for customer's nationality
place_of_birth
nullable
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
nullable
string Date of birth of the customer
gender
nullable
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
nullable
string E-mail address of customer. Maximum length 50 characters
mobile_number
nullable
string Mobile number of customer in E.164 format

Maximum length 50 characters
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • VND - Only supports positive integers.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to complete the payment. Typical actions are for merchant to trigger OTP validation or redirect your customer to an authentication page.
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
  • SUCCEEDED - The payment was successfully completed.
  • FAILED - The payment request failed. See failure_code for the specific reason why the transaction failed.
  • AWAITING_CAPTURE - The payment request is eligible for manual capture and is awaiting the trigger of the manual Capture API.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to complete a payment. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
capture_method
nullable
string Describes when the funds are captured.
Defaults to AUTOMATIC
Possible values:
  • AUTOMATIC
  • MANUAL - Only supported for payment method type CARD
initiator
required
string Identifies whether the payment is initiated by the end-customer or the merchant.
Defaults to CUSTOMER
Possible values:
  • CUSTOMER - The transaction was initiated by the payor
  • MERCHANT - The transaction was initiated by the merchant
channel_properties
nullable
object Specific settings applied to the payment request, overwriting the ones in the Payment Method object.
For multiple use OVO, and SHOPEEPAY (ID & MY):
Key Value
redeem_points
nullable
string Indicates whether or not to use the Payment Method's points_balance in the transaction
Possible values:
  • REDEEM_NONE - No points will be used
  • REDEEM_ALL - points will be used to offset payment amount before cash balance is used.
    REDEEM_ALL can only be used when approved by OVO for promotions.
    For SHOPEEPAY (ID), only up to 50% of the transaction amount (rounded down) can be paid using SHOPEEPAY coins.
Default value: REDEEM_NONE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful

For SHOPEEPAY(VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending

For PAYMAYA:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
nullable
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.

For WECHATPAY (MY):
Key Value
device_type
required
string determines the device type of the end user. Accepts the following values:
  • DESKTOP
  • MOBILE
payer_ip_address
nullable
string The IP address of the end user's client (e.g. 192.168.0.1)
Required if device_type is set to MOBILE
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending
Required if device_type is set to MOBILE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
Required if device_type is set to MOBILE
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization has failed
Required if device_type is set to MOBILE

For BRI Direct Debit:
Key Value
require_auth
nullable
string Toggle used to require end-customer to input undergo OTP validation before completing a payment.
  • true
  • false
Default value: true

For BPI, UBP, RCBC, CHINABANK Direct Debit:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed


For SCB and BBL Direct Debit:
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.


For KTB and BAY Direct Debit:
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.


For CARD:
Key Value
skip_three_d_secure
required
boolean To indicate whether to perform 3DS on the payment request
Defaults to false
success_return_url
nullable
string URL where the end-customer is redirected if the linking is successful.
Required when skip_three_d_secure = false.
This will be null if not applicable.
failure_return_url
nullable
string URL where the end-customer is redirected if the linking has failed.
Required when skip_three_d_secure = false.
This will be null if not applicable.
merchant_id_tag
nullable
string Tag for the Merchant ID that you want to associate this payment with. This is for merchants using their own MIDs to specify which MID they want to use
cardonfile_type
nullable
string Type of โ€œcredential-on-fileโ€ / โ€œcard-on-fileโ€ / COF payment for subsequent usage. Indicates future card-on-file usage.
If you intend for a card to be used for future COF transactions, then this value must be included so that Xendit can inform the processors of this setup, and then after that on every transaction following the first transaction.
Default: CUSTOMER_UNSCHEDULED
Possible values:
  • CUSTOMER_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments that do not follow a schedule.
    Example: simple โ€œsave card for future checkoutโ€ eCommerce flow, the future payments would always be CUSTOMER_UNSCHEDULED
  • MERCHANT_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments initiated without customer interaction and do not follow a schedule
    Example: auto top-up payment flow
  • RECURRING - If you intend to use this Payment Method to process a series of transactions at fixed, regular intervals.
    Example: Subscriptions

Notes: In order to process MERCHANT_UNSCHEDULED and RECURRING card-on-file transaction types:
  • Aggregator Merchant will need to be allowed to perform transaction without 3DS, please check this guide for self-serve or contact Xendit representative for enabling 3DS as optional
  • Switcher Merchant with their own acquiring bank MID will need to have MID for non 3DS transactions and support recurring configured by the acquirer.

For GRABPAY (MY):
Key Value
allowed_payment_options
nullable
Array of enums
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Usage for each Payment method reusability
  • ONE_TIME_USE - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
  • MULTIPLE_USE - Choose One payment option to use, default will use GrabPay Ewallet balance

shipping_information
nullable
object Object containing the payor's shipping address.
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customerโ€™s shipping country
street_line1
nullable
string Building name and apartment unit number
street_line2
nullable
string Building street address
city
nullable
string City, village or town as appropriate
province_state
nullable
string Either one of (whichever is applicable):
  • Geographic area, province, or region
  • Formal state designation within country
postal_code
nullable
string Postal, zip or rural delivery code, if applicable
card_verification_results
nullable
object This is only applicable for CARD transactions. This contains the results of various checks done to verify the transaction such as CVV, and AVS.
Key Value
three_d_secure
nullable
object Only applicable for Payment Requests when 3DS is performed
Indicates the result of any 3DS transaction initiated when Payment Request creation is performed using 3DS.
Note that each 3DS transaction performed using a unique Payment Method will be unique and may have a different three_ds_result unique for each Payment Request.

Key Value
three_d_secure_flow
required
string Whether the 3DS transaction went through a frictionless or challenge flow.
Possible values:
  • FRICTIONLESS - 2FA was not required
  • CHALLENGE - 2FA was required via OTP or other means
eci_code
required
string Electronic Commerce Indicator (ECI) is a number that indicates the level of security that was used when obtaining the customerโ€™s payment credentials.
An ECI is included as part of the authorization request for each transaction.
Possible values:
  • 00 - Unable to authenticate (Mastercard)
  • 01 - Authentication attempted (Mastercard)
  • 02 - Successful authentication (Mastercard)
  • 05 - Successful authentication (Visa, AMEX, JCB)
  • 06 - Authentication attempted (Visa, AMEX, JCB)
  • 07 - Unable to authenticate (Visa, AMEX, JCB)
three_d_secure_result
required
string The result of the 3DS authentication.
Possible values:
  • SUCCESSFUL [ECI 02 / 05] - 3DS authentication was successful. Liability shift available.
  • ATTEMPTED [ECI 01 / 06] - 3DS authentication was attempted, but not completed. This could be due to either: issuer does not support 3DS, issuer supports 3DS but card not enabled for 3DS, or issuer 3DS server experiencing an outage. In most cases, liability shift is available
  • FAILED [ECI 00 / 07] - 3DS authentication failed. Liability shift not available. authorization request must not be submitted.
  • NOT_AVAILABLE [No ECI code being returned] - 3DS could not be performed on this card. In most cases, you can proceed to authorization request but liability shift will not be available.
  • PROCESSING_ERROR [No ECI code being returned] - An issue occurred with the issuerโ€™s 3DS server or with the card processor, and no proof of any 3DS attempt can be provided. In most cases, liability shift will not be available.
three_d_secure_version
nullable
string Indicates the 3DS version.

Possible values:
  • null - if no 3DS version returned by the processor
  • 1.0.x - 3DS version 1.0, the basic version. From 2021 onwards, high chance that there will be no chargeback liability shift for payments using 3DS 1.0.
  • 2.1.x - Minimum version returned for EMV 3DS. Frictionless authentication is possible.
  • 2.2.x - Upgraded version returned for EMV 3DS. Returned if more advanced authentication methods are used, such as biometrics.
cvv_result
nullable
Indicates the result from verifying the Card Validation Value / Card Validation Code (CVV / CVC) when creating the Payment Method / token.
Possible values:
  • MATCHED - CVV entered matched issuerโ€™s records.
  • NOT_MATCHED - CVV entered did not match issuerโ€™s records. Try entering the CVV again or a different card.
  • NOT_PROCESSED - CVV entered was not processed, for an unspecified reason. Try repeating the transaction and re-entering the CVV.
  • NOT_INCLUDED - CVV exists on the card but was not included in the request
  • VALIDATION_FAILED - CVV entered failed data validation. Try repeating the transaction and re-entering the CVV.
  • SUSPICIOUS_TRANSACTION - The transaction was considered suspicious by the issuer. Try a different card.
  • NOT_SUPPORTED - CVV verification is not supported by the issuer, card association, or processor.
  • UNKNOWN_FROM_PROCESSOR - Unrecognized or no result code returned by processor.
address_verification_result
nullable
Only applicable for cards issued in USA, CAN or the UK.
Indicates the result from verifying the street address and zip code provided when creating the Payment Request.
Possible values:
  • MATCHED - Street address and zip code match.
  • NOT_MATCHED - Street address and zip code entered do not match issuerโ€™s records. Try repeating the transaction and re-entering the address and zip.
  • NOT_MATCHED_NAME - Street address and zip code entered match issuerโ€™s records, but not cardholder name. Try repeating the transaction and re-entering the cardholder name.
  • PARTIAL_MATCH_ADDRESS - Street address entered matches issuerโ€™s records, but not the zip code. Try repeating the transaction and re-entering the zip and/or cardholder name.
  • PARTIAL_MATCH_ZIP - Zip code entered matches issuerโ€™s records, but not the street address. Try repeating the transaction and re-entering the address and/or cardholder name.
  • PARTIAL_MATCH_NAME - Cardholder name entered matches issuerโ€™s records, but not the street address and zip code. Try repeating the transaction and re-entering the street address and zip.
  • INVALID - Address verification data provided was invalid, or it is not allowed for this card type.
  • NOT_SUPPORTED - Address verification is not supported for this card
  • NOT_AVAILABLE - The address verification system is temporarily unavailable. Try repeating the transaction again later.
  • UNKNOWN_FROM_PROCESSOR - The processor returned an unrecognized value for the address verification response.
failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
See possible codes here.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.
items
nullable
array Array of objects describing the item/s purchased

Object parameters
Key Value
type
required
string Type of item

DIGITAL_PRODUCT, PHYSICAL_PRODUCT, DIGITAL_SERVICE, PHYSICAL_SERVICE,FEE,DISCOUNT (Atome does not support DISCOUNT)
reference_id
required
string Merchantโ€™s identifier for specific item (ie. SKU, promotion code, etc)

Format Special and alphanumeric
Max length 255 characters
name
required
string Item name

Format Special and alphanumeric
Max length 255 characters
net_unit_amount
required
number Net amount to be charged per unit, please put negative amount for DISCOUNT (e.g. -1000000)
quantity
required
number Number of units of this item in the basket

Min 1
url
required
string URL of the item

Must be HTTPS or HTTP
category
required
string Merchant category for item

Format Special and alphanumeric
Max length 255 characters
subcategory
optional
string Merchant subcategory for item

Format Special and alphanumeric
Max length 255 characters
description
optional
string Item description

Format Special and alphanumeric
Max length 255 characters
metadata
optional
object Additional object that may be used for additional item attributes

Payment Method Object

This object is refered to the source of funds or the payment instrument used for the payment. This may also refer to linked/tokenized cards, bank accounts, payment instrument (virtual account number, QR codes, or fixed payment code) or e-wallet accounts.

Payment Method Object Example

{
    "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
    "card": null,
    "type": "DIRECT_DEBIT",
    "status": "ACTIVE",
    "actions": [],
    "country": "PH",
    "created": "2022-08-12T13:30:26.579048Z",
    "ewallet": null,
    "qr_code": null,
    "updated": "2022-08-12T13:30:58.908220358Z",
    "metadata": null,
    "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
    "description": null,
    "reusability": "MULTIPLE_USE",
    "direct_debit": {
        "type": "BANK_ACCOUNT",
        "debit_card": null,
        "bank_account": {
            "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
            "masked_bank_account_number": "XXXXXX1234"
        },
        "channel_code": "BPI",
        "channel_properties": {
            "failure_return_url": "https://your-redirect-website.com/failure",
            "success_return_url": "https://your-redirect-website.com/success"
        }
    },
    "failure_code": null,
    "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
    "virtual_account": null,
    "over_the_counter": null,
    "billing_information": null,
    "direct_bank_transfer": null,
    "business_id": "5f27a14a9bf05c73dd040bc8"
}


Body Parameter Type Description
id
required
string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
customer
nullable
object A customer object to skip Create Customer URL endpoint process. This object is required for all DIRECT_DEBIT payment methods and MULTIPLE_USE EWALLETs if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
nullable
string Last or family name of customer
nationality
nullable
string Country code for customer's nationality
place_of_birth
nullable
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
nullable
string Date of birth of the customer
gender
nullable
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
nullable
string E-mail address of customer. Maximum length 50 characters
mobile_number
nullable
string Mobile number of customer in E.164 format

Maximum length 50 characters
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

Possible values:
  • ONE_TIME_USE
  • MULTIPLE_USE
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
  • ACTIVE - The payment method can be used for payment requests (for Cards, E-wallets, Direct Debit) or can now accept payments (for Virtual Account, Over-the-Counter, QR Code)
  • INACTIVE - Merchant-toggled status to temporarily prevent further transactions from the payment method. This status is reversible.
  • EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible.
  • PENDING - The request is successfully passed, and need to acivate asynchronously. Please listen to our callback to get the updated status.
  • FAILED - For Cards Payment Methods, this means the card was not successfully tokenized. For Direct Debit Payment Methods, this indicates that the account is already linked for the cend customer.
actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
type
required
string Type of payment method. Refer to the corresponding object to access further information

Possible values:
  • EWALLET
  • DIRECT_DEBIT
  • CARD
  • VIRTUAL_ACCOUNT
  • OVER_THE_COUNTER
  • QR_CODE
ewallet
nullable
object For type='EWALLET', this contains the necessary information to describe an ewallet payment method. This will be null otherwise.
Please refer to Ewallet Object for more parameter details.
direct_debit
nullable
object For type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method. This will be null otherwise.
Please refer to Direct debit Object for more parameter details.
card
nullable
object For type='CARD', this contains the necessary information to describe a Card payment method. This will be null otherwise.
Please refer to Card Object for more parameter details.
over_the_counter
nullable
object For type='OVER_THE_COUNTER', this contains the necessary information to describe an over-the-counter payment method. This will be null otherwise.
Please refer to OTC Object for more parameter details.
virtual_account
nullable
object For type='VIRTUAL_ACCOUNT', this contains the necessary information to describe a virtual account payment method. This will be null otherwise.
Please refer to Virtual Account Object for more parameter details.
qr_code
nullable
object For type='QR_CODE', this contains the necessary information to describe a QR Code payment method. This will be null otherwise.
Please refer to QR Object for more parameter details.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
billing_information
nullable
object Object containing the payor's billing address. For CARD, this should match the billing information on record with the cardholder's issuer.
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customerโ€™s country of residence
street_line1
nullable
string Building name and apartment unit number
street_line2
nullable
string Building street address
city
nullable
string City, village or town as appropriate
province_state
nullable
string Either one of (whichever is applicable):
  • Geographic area, province, or region
  • Formal state designation within country
postal_code
nullable
string Postal, zip or rural delivery code, if applicable
failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
See possible codes here.
created
required
string ISO 8601 Timestamp for Payment Method object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Method object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Method creation.

Cards Object

Card Object Example

{
    "currency": "IDR",
    "channel_properties": {
        "skip_three_d_secure": null,
        "success_return_url": "https://redirect.me/goodstuff",
        "failure_return_url": "https://redirect.me/badstuff",
        "cardonfile_type": null
    },
    "card_information": {
        "token_id": "651d1fa8e16b180017aab0f0",
        "masked_card_number": "40000000XXXX1091",
        "cardholder_name": "John Doe",
        "expiry_month": "12",
        "expiry_year": "2040",
        "type": "CREDIT",
        "network": "VISA",
        "country": "ID",
        "issuer": "BRI",
        "fingerprint": "636a577b635d29001b94f2fe",
        "cardholder_email": "johndoe@gmail.com",
        "cardholder_phone_number": "628212223242526"
    },
    "card_verification_results": {
        "address_verification_result": "MATCH",
        "cvv_result": "MATCH",
        "three_d_secure": {
            "eci_code": "05",
            "three_d_secure_flow": "CHALLENGE",
            "three_d_secure_result": "AUTHENTICATED",
            "three_d_secure_result_reason": null,
            "three_d_secure_version": "2.1.0"
        }
    },
    "card_data_id": null,
    "is_cvn_submitted": null
}

Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
  • USD
channel_properties
required
object Information provided specific to the channel partner that was provided during the request
Key Value
skip_three_d_secure
nullable
boolean This field value is only configurable for reusability = MULTIPLE_USE to indicate whether to perform 3DS during the linking phase.
Defaults to false
success_return_url
nullable
string URL where the end-customer is redirected if the linking is successful.
Required when skip_three_d_secure = false.
This will be null if not applicable.
failure_return_url
nullable
string URL where the end-customer is redirected if the linking has failed.
Required when skip_three_d_secure = false.
This will be null if not applicable.
cardonfile_type
nullable
string Type of โ€œcredential-on-fileโ€ / โ€œcard-on-fileโ€ / COF payment for subsequent usage. Indicates future card-on-file usage.
If you intend for a card to be used for future COF transactions, then this value must be included so that Xendit can inform the processors of this setup, and then after that on every transaction following the first transaction.
Default: CUSTOMER_UNSCHEDULED
Possible values:
  • CUSTOMER_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments that do not follow a schedule.
    Example: simple โ€œsave card for future checkoutโ€ eCommerce flow, the future payments would always be CUSTOMER_UNSCHEDULED
  • MERCHANT_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments initiated without customer interaction and do not follow a schedule
    Example: auto top-up payment flow
  • RECURRING - If you intend to use this Payment Method to process a series of transactions at fixed, regular intervals.
    Example: Subscriptions

Notes: In order to process MERCHANT_UNSCHEDULED and RECURRING card-on-file transaction types:
  • Aggregator Merchant will need to be allowed to perform transaction without 3DS, please check this guide for self-serve or contact Xendit representative for enabling 3DS as optional
  • Switcher Merchant with their own acquiring bank MID will need to have MID for non 3DS transactions and support recurring configured by the acquirer.
card_information
required
object Information pertaining to the actual card
Key Value
token_id
required
string Corresponding token ID of the card
masked_card_number
required
string Masked card number
cardholder_name
required
string Cardholder's name. Issuer will use this information to assess the transaction.
character: Alphanumeric. No special characters are allowed.
cardholder_email
required
string Card holder's email address. Issuer will use this information to assess the transaction.
cardholder_phone_number
required
string Card holder's phone number or mobile number. Issuer will use this information to assess the transaction.
character: use +(country_code) as prefix. No - and/or blank space is allowed. Follow ITU-E.164 Standard
expiry_month
required
string Card expiry month in MM format.
expiry_year
required
number Card expiry year in YYYY format.
type
nullable
string Type of card used.
Possible values:
  • CREDIT
  • DEBIT
network
nullable
string Card scheme of the card specified for tokenization.
Possible values:
  • VISA
  • MASTERCARD
  • JCB
  • AMEX
country
nullable
string 2-letter country code of the issuing country of the card
issuer
nullable
string Name of the issuing entity of the card
fingerprint
nullable
number Unique consistent identifier for the card. This does not change values over different authorizations.
card_verification_results
required
object For card transactions, this contains the results of various checks done such as 3DS, CVV, and AVS.
Key Value
address_verification_result
nullable
string Only applicable for issuer banks that support address checks, generally works for issuer banks in the US, CA, or the UK
Possible values:
  • MATCHED
  • NOT_MATCHED
  • NOT_MATCHED_NAME
  • PARTIAL_MATCH_ADDRESS
  • PARTIAL_MATCH_ZIP
  • PARTIAL_MATCH_NAME
  • INVALID
  • NOT_SUPPORTED
  • NOT_AVAILABLE
  • UNKNOWN_FROM_PROCESSOR
cvv_result
nullable
string Indicates the result from verifying the Card Validation Value / Card Validation Code (CVV / CVC) when creating the Payment Method / token.
Possible values:
  • MATCHED
  • NOT_MATCHED
  • NOT_PROCESSED
  • NOT_INCLUDED
  • VALIDATION_FAILED
  • SUSPICIOUS_TRANSACTION
  • NOT_SUPPORTED
  • UNKNOWN_FROM_PROCESSOR
three_d_secure
nullable
object Only applicable for Payment Methods when 3DS is performed. Indicates the result of any 3DS transaction initiated when Payment Method creation is performed using 3DS.
Key Value
three_d_secure_flow
nullable
string Whether the 3DS transaction went through a frictionless or challenge flow. Frictionless - no 2FA. Challenge - 2FA was required via OTP or other.
Possible values:
  • CHALLENGE
  • FRICTIONLESS
eci_code
nullable
string Electronic Commerce Indicator (ECI) is a number that indicates the level of security that was used when obtaining the customerโ€™s payment credentials.An ECI is included as part of the authorization request for each transaction.
Possible values:
  • 00 - Unable to authenticate (Mastercard)
  • 01 - Authentication attempted (Mastercard)
  • 02 - Successful authentication (Mastercard)
  • 05 - Successful authentication (Visa, AMEX, JCB)
  • 06 - Authentication attempted (Visa, AMEX, JCB)
  • 07 - Unable to authenticate (Visa, AMEX, JCB)
three_d_secure_result
nullable
string Only applicable for Payment Methods when 3DS is performed. Indicates the result of any 3DS transaction initiated when Payment Method creation is performed using 3DS.
Possible values:
  • SUCCESSFUL [ECI 02 / 05]
  • ATTEMPTED [ECI 01 / 06]
  • FAILED [ECI 00 / 07]
  • NOT_AVAILABLE [No ECI code being returned]
  • PROCESSING_ERROR [No ECI code being returned]
three_d_secure_result_reason
nullable
string Elaboration on the 3DS authentication result, where available
Possible values:
  • CARD_NOT_ENROLLED
  • NETWORK_NOT_SUPPORTED
  • ABANDONED
  • CANCELED
  • REJECTED
  • BYPASSED
  • PROCESSOR_ERROR
three_d_secure_version
nullable
string Indicates the 3DS version.
Possible values:
  • null
  • 1.0.x
  • 2.1.x
  • 2.2.x

card_data_id
nullable
string Unique consistent identifier for the card. This does not change values over different authorizations.
is_cvn_submitted
nullable
boolean Whether CVN was provided as part of the tokenization step.

Direct Debit Object

Direct Debit Object Example

{
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "ed9c7984efecd163b0ffc4d79240fb64477592bdcce6cc0f7dd43ee4018bc4c2",
                "masked_bank_account_number": "XXXXXXX3213"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://redirect.me/badstuff",
                "success_return_url": "https://redirect.me/goodstuff"
            }
}

Body Parameter Type Description
channel_code
required
string Identifier for the payment channel partner.
Possible values:
  • Indonesia
    • BRI
    • MANDIRI
  • Philippines
    • BPI
    • BPI_RECURRING
    • UBP
    • UBP_EADA
    • RCBC
    • CHINABANK
    • BDO_EPAY
  • Thailand
    • SCB
    • KTB
    • BBL
    • BAY
    • SCB_MB
    • KTB_MB
    • BBL_MB
    • BAY_MB
    • KBANK_MB
  • Malaysia
    • FPX Channels, listed here
channel_properties
required
object object Information provided specific to the channel partner that was provided during the request

Key Value
success_return_url
conditional
string URL where the end-customer is redirected if the authorization is successful.
This will be null if not applicable. This parameter is required for all channels except BRI.
failure_return_url
conditional
string URL where the end-customer is redirected if the authorization has failed.
This will be null if not applicable. This parameter is required for all channels except BRI.
mobile_number
conditional
string Registered mobile number of the end-customer to the channel partner in E.164 Format. This parameter is required for BRI.
This will be null if not applicable.
card_last_four
conditional
string Last four digits of the debit card. This parameter is required for BRI.
This will be null if not applicable.
card_expiry
nullable
string Expiry month and year of the debit card (in MM/YY format).
This will be null if not applicable.
email
nullable
string Email address of the customer that is registered to the partner channel.
This will be null if not applicable.
identity_document_number
nullable
string The account holder's ID Card number or passport number. Required for BAY and KTB
This will be null if not applicable.
bank_account
nullable
object object If direct_debit.type='BANK_ACCOUNT', this contains details regarding the underlying bank account of the payment method. This will be null otherwise.
Key Value
masked_bank_account_number
nullable
string Masked account details as provided by the bank. This can be used for displaying a portion of the account number. This will be null if unavailable.
bank_account_hash
nullable
string Unique hash for the specific account. This does not change across different authorizations or integrations. This will be null if unavailable.
debit_card
nullable
object object If direct_debit.type='DEBIT_CARD', this contains details regarding the debit card to be used for payments. This will be null otherwise.
Key Value
mobile_number
nullable
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
This will be null if not applicable.
card_last_four
nullable
string Last four digits of the debit card.
This will be null if not applicable.
card_expiry
nullable
string Expiry month and year of the debit card (in MM/YY format).
This will be null if not applicable.
email
nullable
string Email address of the customer that is registered to the partner channel.
This will be null if not applicable.

E-Wallets Object

E-Wallets Object Example

{
            "account": {
                "name": "John  Doe",
                "balance": null,
                "point_balance": null,
                "account_details": "+62123456XXXX"
            },
            "channel_code": "OVO",
            "channel_properties": {
                "failure_return_url": "https://redirect.me/badstuff",
                "success_return_url": "https://redirect.me/goodstuff"
            }
}
Body Parameter Type Description
channel_code
required
string Identifier for the payment channel partner.
Possible values:
  • Indonesia
    • DANA
    • OVO
    • LINKAJA
    • ASTRAPAY
    • JENIUSPAY
    • SHOPEEPAY
    • SAKUKU
  • Philippines
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • GCASH
  • Vietnam
    • APPOTA
    • MOMO
    • ZALOPAY
    • VNPTWALLET
    • SHOPEEPAY
    • VIETTELPAY
  • Thailand
    • WECHATPAY
    • LINEPAY
    • SHOPEEPAY
    • TRUEMONEY
  • Malaysia
    • TOUCHNGO
    • SHOPEEPAY
    • GRABPAY
    • WECHATPAY
channel_properties
required
object Information provided specific to the channel partner that was provided during the request
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful.
This will be null if not applicable.
failure_return_url
required
string URL where the end-customer is redirected if the authorization has failed.
This will be null if not applicable.
cancel_return_url
nullable
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes. Only supported by PAYMAYA
This will be null if not applicable.
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending.
This will be null if not applicable.
Required for WECHATPAY (MY) and device_type is set to MOBILE.
mobile_number
nullable
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
This will be null if not applicable.
device_type
nullable
string determines the device type of the end user. Accepts the following values:
  • DESKTOP
  • MOBILE
Only supported by WECHATPAY (MY) and defaults to DESKTOP if not provided.
payer_ip_address
nullable
string The IP address of the end user's client (e.g. 192.168.0.1)
Only supported by WECHATPAY (MY)
Required if device_type is set to MOBILE
allowed_payment_options
nullable
Array of enums specific for GRABPAY (MY)
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Usage for each Payment method reusability
  • ONE_TIME_USE - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
  • MULTIPLE_USE - Choose One payment option to use, default will use GrabPay Ewallet balance
account
nullable
object Object that contains information of the linked eWallet account. Will be null if information is not available.
Key Value
account_details
nullable
string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable.
name
nullable
string Name of the eWallet account holder. This will be null if unavailable.
balance
nullable
number Current available balance in the eWallet. This will be null if unavailable.
point_balance
nullable
number Current available points in the eWallet for consumption. This will be null if unavailable.

Retail Outlet (OTC) Object

Over-the-counter Object Example

 {
            "amount": 10000,
            "currency": "IDR",
            "channel_code": "INDOMARET",
            "channel_properties": {
                "payment_code": "TESTABCD1234",
                "customer_name": "John Doe",
                "expires_at": "2023-06-22T04:40:51Z"
            }
        }

Body Parameter Type Description
channel_code
required
string Identifier for the payment channel partner
Possible values:
  • Indonesia
    • ALFAMART
    • INDOMARET
  • Philippines
    • 7ELEVEN
    • 7ELEVEN_CLIQQ
    • CEBUANA
    • ECPAY
    • PALAWAN
    • MLHUILLIER
    • ECPAY_DRAGONLOAN
    • SM_BILLS
    • ROBINSONS_BILLS

currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
amount
nullable
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding payment code will accept any amount as payment (open amount).
channel_properties
required
object Information provided specific to the channel partner that was provided during the request
Key Value
customer_name
required
string Complete name of the payor. May be used by the channel partner to verify their identity. Must contain letters and space only.
payment_code
nullable
string The corresponding payment code to be given to the Customer to be presented at OTC partner channels.
expires_at
required
string Timestamp in ISO 8601 UTC+0 for when the payment code will be valid.

QR Object

QR Object Example

 {
            "amount": 15000,
            "channel_code": "DANA",
            "channel_properties": {
                "expires_at": "2023-06-02T07:17:32.34039Z",
                "qr_string": "some-random-qr-string"
            },
            "currency": "IDR"
}

Body Parameter Type Description
channel_code
conditional
string Identifier for the QR Code standard used. This parameter is not required for Indonesia channel code.
Possible values:
  • Indonesia
    • DANA
    • LINKAJA
  • Thailand
    • PROMPTPAY

  • Philippines
    • QRPH

currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • VND
  • THB
  • PHP
amount
nullable
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • VND - Only supports positive integers.
  • THB - Supports up to two decimal places.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding QR will accept any amount as payment (open amount). Open amount QR is not supported for QRPH at the moment.
channel_properties
required
object Information regarding the payment method / instrument
Key Value
qr_string
required
string QR string to be rendered for display to end users.

Virtual Account Object

Virtual Account Object Example

 {
            "amount": 100000,
            "channel_code": "BRI",
            "channel_properties": {
                "customer_name": "John Doe",
                "expires_at": "2054-05-24T17:00:00Z",
                "virtual_account_number": "920019999095203"
            },
            "currency": "IDR",
            "alternative_displays": [
              {
                "type": "QR_STRING",
                "data": "SAMPLE_QR_DATA"
              }
            ]
}

Body Parameter Type Description
channel_code
required
string Identifier for the payment channel partner
Possible values:
  • Indonesia
    • BCA
    • BSI
    • BJB
    • CIMB
    • SAHABAT_SAMPOERNA
    • ARTAJASA
    • BRI
    • BNI
    • MANDIRI
    • PERMATA
  • Vietnam
    • PV
    • VIETCAPITAL
    • WOORI
    • MSB
    • VPB
    • BIDV
  • Thailand
    • STANDARD_CHARTERED
  • Malaysia
    • UOB
    • AMBANK
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • VND
  • THB
  • MYR
amount
nullable
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • VND - Only supports positive integers.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

If amount is not provided, the corresponding virtual account will accept any amount as payment (open amount).
channel_properties
required
object Information provided specific to the channel partner that was provided during the request

Key Value
customer_name
required
string Complete name of the payor. May be used by the channel partner to verify their identity.
virtual_account_number
string The corresponding virtual account number that can be used by Customers to send payments to.

Note: This value is ignored for Vietnam and Thailand virtual accounts.
expires_at
required
string Timestamp in ISO 8601 UTC+0 for when the virtual account will be valid.
suggested_amount
nullable
string Provided suggested amount to be paid. Will be visible to the Customer on supported channels.
alternative_display_types
nullable
array of strings Alternative display type for the virtual account.

Note:This value is currently only applicable to Vietnam virtual accounts.

Accepted values:
  • QR_STRING
alternative_displays
nullable
array of object Alternative displays for the virtual account based on alternative_display_types value during request.

Note:This value is currently only applicable to Vietnam virtual accounts.

Contains an array with the following data:
Key Value
type
required
string The type of alternative display
data
required
string The data for the alternative display

Note: For QR_STRING, please use this data to generate a VietQR QR Code.

Refund Object

The Refund Object represents a request to have a certain amount to be refunded from a succeeded payment.

Refund Object Example

{
    "id": "rfd-69e77490-d2cc-4bf3-8319-e064e121db93",
    "payment_id": "pr-d5fe8554-fbcd-42b3-956d-867376550ed9",
    "invoice_id": "",
    "amount": 3000,
    "payment_method_type": "CARD",
    "channel_code": "",
    "currency": "PHP",
    "status": "SUCCEEDED",
    "reason": "CANCELLATION",
    "reference_id": "9d9c04a9-55c8-4eea-8b09-4109ac10b7f0",
    "failure_code": null,
    "refund_fee_amount": null,
    "created": "2022-09-29T03:37:07.06648896Z",
    "updated": "2022-09-29T03:37:07.06648906Z",
    "metadata": null
}
Body Parameter Type Description
id
required
string Unique identifier for the refund request. It will have the prefix rfd-.
payment_id
required
string Identifier for the corresponding Payment that is being refunded
invoice_id
nullable
string If the refund request was made using the ID for a Invoice/Checkout/Payment Link, this is the corresponding identifier for it.
payment_method_type
required
string Type of the payment method used in the original payment.
Possible values:
  • CARD
  • EWALLET
  • DIRECT_DEBIT

reference_id
nullable
string Identifier provided by the merchant for the refund request. This may be automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
amount
required
string Amount of the transaction reflecting the actual decimal places. (Ex. 1234.56 with currency PHP is one thousand thirty-four pesos and fifty-six centavos)
Decimal places support varies per currency:
  • IDR - Only supports whole numbers (can't support decimal number).
  • VND - Only supports whole numbers (can't support decimal number).
  • PHP - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
currency
required
string Three-letter ISO 4217 currency code of the transaction, in uppercase.
status
required
string Status of the refund.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
  • SUCCEEDED
  • FAILED
  • PENDING
  • CANCELLED

country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
channel_code
required
string Identifier for the payment channel partner

reason
required
string Provided reason why the refund was requested.
Possible values:
  • FRAUDULENT
  • DUPLICATE
  • REQUESTED_BY_CUSTOMER
  • CANCELLATION
  • OTHERS
failure_code
nullable
string If the status of the refund is FAILED, this describes the reason for failure.
Will be null if the refund did not fail.
See possible codes here.
refund_fee_amount
nullable
number (if applicable) This will be the corresponding additional fee for processing the refund.
created
required
string ISO 8601 Timestamp for refund object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest refund object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Refund creation.

Payments API Endpoints

Create Payment Request

This endpoint provides the following functionalities:

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "currency": "IDR",
    "amount": 100000,
    "payment_method": {
        "type": "EWALLET",
        "reusability": "ONE_TIME_USE",
        "ewallet": {
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "success_return_url": "https://your-redirect-website.com/success"
            }
        }
    },
    "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
    "metadata": {
        "sku": "ABCDEFGH"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.




Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
amount
conditional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • VND - Only supports positive integers.
Notes:
  • Required for payment method types CARD, EWALLET and DIRECT_DEBIT.
  • For OVER_THE_COUNTER and VIRTUAL_ACCOUNT this will be the expected amount to be paid. If none is provided, the resulting payment instrument will accept any amount as payment.
  • For QR_CODE, this is required for ONE_TIME_USE. For MULTIPLE_USE QR Codes, amount provided will be ignored.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

A customer_id is required for all DIRECT_DEBIT payment methods and MULTIPLE_USE EWALLETs.
customer
optional
object A customer object to skip Create Customer URL endpoint process. This object only available if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • TH - Thailand
  • MY - Malaysia
  • VN - Vietnam
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
conditional
object Note: Only one of payment_method{} or payment_method_id must be present.
Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.
payment_method_id
conditional
object Note: Only one of payment_method{} or payment_method_id must be present.
ID of the ACTIVE Payment Method to be used in the payment.
capture_method
conditional
string Note: Only available for cards
Describes when the funds are captured. Default: AUTOMATIC
Accepted values:
- AUTOMATIC - Capture is done immediately as the request passes validation
- MANUAL - Capture is only done when the Capture endpoint is triggered. This is only applicable for CARD transactions.
channel_properties
optional
object Specific settings to be applied to the transaction. This also overwrites any common parameters with the Payment Method Object.
For multiple use OVO, and SHOPEEPAY (ID & MY):
Key Value
redeem_points
nullable
string Indicates whether or not to use the Payment Method's points_balance in the transaction
Possible values:
  • REDEEM_NONE - No points will be used
  • REDEEM_ALL - points will be used to offset payment amount before cash balance is used.
    REDEEM_ALL can only be used when approved by OVO for promotions.
    For SHOPEEPAY (ID), only up to 50% of the transaction amount (rounded down) can be paid using SHOPEEPAY coins.
Default value: REDEEM_NONE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful

For PAYMAYA:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
nullable
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.

For WECHATPAY (MY):
Key Value
device_type
required
string determines the device type of the end user. Accepts the following values:
  • DESKTOP
  • MOBILE
payer_ip_address
nullable
string The IP address of the end user's client (e.g. 192.168.0.1)
Required if device_type is set to MOBILE
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending
Required if device_type is set to MOBILE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
Required if device_type is set to MOBILE
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization has failed
Required if device_type is set to MOBILE

For BRI Direct Debit:
Key Value
require_auth
nullable
string Toggle used to require end-customer to input undergo OTP validation before completing a payment.
  • true
  • false
Default value: true

For BPI, UBP, RCBC, CHINABANK, and FPX Channels under Direct Debit:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed

For SCB and BBL Direct Debit:
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.


For KTB and BAY Direct Debit:
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.


For GRABPAY (MY):
Key Value
allowed_payment_options
nullable
Array of enums
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Usage for each Payment method reusability
  • ONE_TIME_USE - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
  • MULTIPLE_USE - Choose One payment option to use, default will use GrabPay Ewallet balance

metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
  "id": "pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
  "currency": "IDR",
  "amount": 100000,
  "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "status": "REQUIRES_ACTION",
  "payment_method": {
    "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
    "type": "EWALLET",
    "reusability": "ONE_TIME_USE",
    "status": "ACTIVE",
    "ewallet": {
      "channel_code": "SHOPEEPAY",
      "channel_properties": {
        "success_return_url": "https://your-redirect-website.com/success",
      },
      "account": {
        "account_details": null,
        "name": null,
        "balance": null,
        "point_balance": null
      }
    },
    "direct_debit": null
  },
  "channel_properties": {
    "redeem_points": "REDEEM_NONE"
  },
  "actions": [
    {
      "action": "AUTH",
      "url_type": "WEB",
      "url": "https://link-web.xendit.co/oauth/lat-4ec01c8d-0326-4a35-bc11-b64c85f7408e/confirm",
      "method": "GET"
    }
  ],
  "created": "2020-08-29T09:12:33.001Z",
  "updated": "2020-08-29T09:12:33.001Z",
  "metadata": {
    "sku": "ABCDEFGH"
  }
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
PROCESSOR_CONFIGURATION_ERROR
500
Payment declined due to a problem with the merchant configuration on the Card Processor. Contact Xendit to troubleshoot the issue.
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
PROCESSOR_TEMPORARILY_UNAVAILABLE
503
The Card Processor appears to be temporarily unavailable. Wait for a couple minutes, then resend the request. If it fails again, Cardholder can try using a different card or other form of payment.
PROCESSOR_TIMEOUT_ERROR
503
Request was received by the processor, but there was a server timeout. Wait for a couple minutes and then retry the request.

Get Payment Request by ID

This endpoints returns the corresponding Payment Method that matches the provided ID.

Endpoint: Get Payment Request by ID

GET https://api.xendit.co/payment_requests/:id

Get Payment Request by ID Request

Example Get Payment Request by ID Request

curl https://api.xendit.co/payment_requests/pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f -X GET \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoRe
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Request object.

Get Payment Request by ID Response

Example Get Payment Request by ID Success Response

{
  "id": "pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f",
  "currency": "PHP",
  "amount": 10000,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "status": "SUCCEEDED",
  "reference_id": "a2c66ceb-2cbe-4541-bb69-9f50fd2040e0",
  "payment_method": {
      "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
      "card": null,
      "type": "DIRECT_DEBIT",
      "status": "ACTIVE",
      "actions": [],
      "country": "PH",
      "ewallet": null,
      "qr_code": null,
      "metadata": null,
      "description": null,
      "reusability": "MULTIPLE_USE",
      "direct_debit": {
          "type": "BANK_ACCOUNT",
          "debit_card": null,
          "bank_account": {
              "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
              "masked_bank_account_number": "XXXXXX1234"
          },
          "channel_code": "BPI",
          "channel_properties": {
              "failure_return_url": "https://your-redirect-website.com/failure",
              "success_return_url": "https://your-redirect-website.com/success"
          }
      },
      "failure_code": null,
      "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
      "virtual_account": null,
      "over_the_counter": null,
      "billing_information": null,
      "direct_bank_transfer": null,
      "created": "2022-08-12T13:30:26.579048Z",
      "updated": "2022-08-12T13:30:58.908220358Z"
  },
  "channel_properties": null,
  "actions": [],
  "created": "2020-08-29T09:12:33.001Z",
  "updated": "2020-08-29T09:12:33.001Z",
  "metadata": {
      "sku": "ABCDEFGH"
  }
}

A successful Payment Request retrieval returns the matching Payment Request Object with an HTTP 200 status code.

Get Payment Request by ID Errors

Error Code Description
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue

List Payment Requests

This endpoints returns a list of matching Payment Request objects based on the provided query.

Each unique query string parameter is AND-ed to each other.

Endpoint: List Payment Requests

GET https://api.xendit.co/payment_requests

List Payment Requests Request

Example List Payment Requests Request

curl https://api.xendit.co/payment_requests?reference_id="a2c66ceb-2cbe-4541-bb69-9f50fd2040e0" -X GET \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \ \
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Query String Parameter Type Description
id
optional
string Primary identifier for the Payment Request object.
reference_id
optional
string Merchant-provided identifier for this payment request.
customer_id
optional
string ID of the customer object to which the payment request is attached to.
limit
optional
number Maximum number of resources to be returned in the response. Use after_id and before_id to navigate to other resources.
Default: 10
after_id
optional
string Retrieve all resources created after the provided Payment Request ID
before_id
optional
string Retrieve all resources created before the provided Payment Request ID

List Payment Requests Response

Example List Payment Requests Response

{
  "data": [
      {
        "id": "pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f",
        "currency": "PHP",
        "amount": 10000,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "business_id": "5f27a14a9bf05c73dd040bc8",
        "status": "SUCCEEDED",
        "reference_id": "a2c66ceb-2cbe-4541-bb69-9f50fd2040e0",
        "payment_method": {
            "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
            "card": null,
            "type": "DIRECT_DEBIT",
            "status": "ACTIVE",
            "actions": [],
            "country": "PH",
            "ewallet": null,
            "qr_code": null,
            "metadata": null,
            "description": null,
            "reusability": "MULTIPLE_USE",
            "direct_debit": {
                "type": "BANK_ACCOUNT",
                "debit_card": null,
                "bank_account": {
                    "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                    "masked_bank_account_number": "XXXXXX1234"
                },
                "channel_code": "BPI",
                "channel_properties": {
                    "failure_return_url": "https://your-redirect-website.com/failure",
                    "success_return_url": "https://your-redirect-website.com/success"
                }
            },
            "failure_code": null,
            "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": null,
            "direct_bank_transfer": null,
            "created": "2022-08-12T13:30:26.579048Z",
            "updated": "2022-08-12T13:30:58.908220358Z"
        },
        "channel_properties": null,
        "actions": [],
        "created": "2020-08-29T09:12:33.001Z",
        "updated": "2020-08-29T09:12:33.001Z",
        "metadata": {
            "sku": "ABCDEFGH"
        }
    }
  ],
  "has_more": false
}
Body Parameter Type Description
data
required
array of objects Returns an array of matching Payment Request Objects. Returns empty array when there is no result.
has_more
required
boolean Indicates whether there are more items to be queried with after_id of the last item from the current result.

List Payment Requests Errors

Error Code Description
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue

Refunds API Endpoints

Create Refund

This endpoint initialized the refund process for the provided amount for a given successful payment.

For refunds made for the QR channel within 24 hours of payment, the original fee and VAT are also returned. Take note that not all issuers are supported for QR refunds, for a list of all supported issuers please refer to this section

Endpoint: Create Refund

POST https://api.xendit.co/refunds

Create Refund Request

Example Create Refund Request

curl https://api.xendit.co/refunds -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "payment_request_id": "pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f",
    "reference_id": "b2756a1e-e6cd-4352-9a68-0483aa2b6a2f",
    "currency":"PHP",
    "reason":"CANCELLATION"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Request Body Parameter Type Description
payment_request_id
conditional
string Identifier for the corresponding Payment Request to be refunded
Note: One of payment_request_id or invoice_id must be provided in the request.
reference_id
nullable
string Identifier provided by the merchant for the refund request. This may be automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
invoice_id
conditional
string Identifier for the corresponding Invoice / Payment Link transaction to be refunded
Note: One of payment_request_id or invoice_id must be provided in the request.
currency
nullable
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • MYR
  • VND
  • THB
amount
conditional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • VND - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • THB - Supports up to two decimal places.

Note: If amount is not provided, the refund request will default to the maximum possible amount to be refunded from the provided transaction. Amount is required if payment is 'CARD' type
reason
required
string Provided reason why the refund was requested.
Accepted values:
  • FRAUDULENT
  • DUPLICATE
  • REQUESTED_BY_CUSTOMER
  • CANCELLATION
  • OTHERS
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Refund Response

Example Create Refund Response

{
    "id": "rfd-6f4a377d-a201-437f-9119-f8b00cbbe857",
    "payment_id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
    "invoice_id": null,
    "amount": 10000,
    "payment_method_type": "DIRECT_DEBIT",
    "channel_code": "BPI",
    "currency": "PHP",
    "status": "SUCCEEDED",
    "reason": "CANCELLATION",
    "reference_id": "b2756a1e-e6cd-4352-9a68-0483aa2b6a2",
    "failure_code": null,
    "refund_fee_amount": null,
    "created": "2020-08-30T09:12:33.001Z",
    "updated": "2020-08-30T09:12:33.001Z",
    "metadata": null
}

A successful Refund creation returns a Refund Object with an HTTP 201 status code.
Listen to the refund.* callbacks for the final status of the transaction.

Create Refund Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
INELIGIBLE_TRANSACTION
400
Error because the transaction provided has either been fully refunded or was never successful
INSUFFICIENT_BALANCE
400
Error because there is no sufficient balance in your Xendit balance to perform the refund
MAXIMUM_REFUND_AMOUNT_REACHED
400
Error because the provided amount is greater than the allowed refund amount.
PARTIAL_REFUND_NOT_SUPPORTED
400
Error because the partner channel for the transaction does not support partial transactions
REFUND_NOT_SUPPORTED
400
Refund request failed because refunds are not supported by the channel.
REFUND_IN_PROGRESS
400
Concurrent refund requests to a single transaction are not allowed. Please wait for the pending full refund request to be completed before initiating a new one
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The downstream provider will be notified to resolve this issue

Get Refund by ID

This endpoints returns the corresponding Refund that matches the provided ID.

Endpoint: Get Payment Request by ID

GET https://api.xendit.co/refunds/:id

Get Refund by ID Request

Example Get Refund by ID Request

curl https://api.xendit.co/refunds/rfd-6f4a377d-a201-437f-9119-f8b00cbbe857 -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Refund object.

Get Refund by ID Response

Example Get Refund by ID Success Response

{
    "id": "rfd-6f4a377d-a201-437f-9119-f8b00cbbe857",
    "payment_id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
    "invoice_id": null,
    "amount": 10000,
    "payment_method_type": "DIRECT_DEBIT",
    "channel_code": "BPI",
    "currency": "PHP",
    "status": "SUCCEEDED",
    "reason": "CANCELLATION",
    "reference_id": "b2756a1e-e6cd-4352-9a68-0483aa2b6a2",
    "failure_code": null,
    "refund_fee_amount": null,
    "created": "2020-08-30T09:12:33.001Z",
    "updated": "2020-08-30T09:12:33.001Z",
    "metadata": null
}

A successful Payment Request retrieval returns the matching Refund Object with an HTTP 200 status code.

Get Refund by ID Errors

Error Code Description
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue

Tokenization API Endpoints

Create Payment Method

This endpoint is used for account linking which provides the following functionalities:

Explore detailed scenario-based information on various payment methods:

Endpoint: Create Payment Method

POST https://api.xendit.co/v2/payment_methods

Create Payment Method Request

Example Create Payment Method Request

curl https://api.xendit.co/v2/payment_methods -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "type": "EWALLET",
      "reusability": "MULTIPLE_USE",
      "ewallet": {
        "channel_code": "OVO",
        "channel_properties": {
          "success_return_url": "https://your-redirect-website.com/success",
          "failure_return_url": "https://your-redirect-website.com/failure"
        }
      },
      "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information


Request Body Parameter Type Description
type
required
string Type of payment method
Accepted values:
  • CARD
  • EWALLET
  • DIRECT_DEBIT
  • OVER_THE_COUNTER
  • QR_CODE
  • VIRTUAL_ACCOUNT
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For VIRTUAL_ACCOUNT, OVER_THE_COUNTER, and QR_CODE, this determines whether or not the payment instrument stays valid after a successful payment is made.

For CARD, EWALLET, and DIRECT_DEBIT, this determines whether or not authentication is performed again for subsequent payments.

Accepted values:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
  • MULTIPLE_USE - Payment method is tokenized and may be reused for subsequent payments.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.

For OVER_THE_COUNTER, QR_CODE, and VIRTUAL_ACCOUNT, this will be extended to the actual payments made.

Maximum length: 255 characters
customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID. The value will always have prefix cust-xxx

A customer_id is required for all DIRECT_DEBIT payment methods and MULTIPLE_USE EWALLETs. Except that, you need to ignore this parameter or set as null.
customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is required for all DIRECT_DEBIT payment methods and MULTIPLE_USE EWALLETs if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL
individual_detail
conditional
object JSON object containing details of the individual.
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • VN - Vietnam
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
billing_information
optional
object Object containing the payor's billing address. For CARD, this should match the billing information on record with the cardholder's issuer.
This is recommended for 3DS 2 / AVS.
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customerโ€™s country of residence
street_line1
optional
string Building name and apartment unit number
street_line2
optional
string Building street address
city
optional
string City, village or town as appropriate
province_state
optional
string Either one of (whichever is applicable):
  • Geographic area, province, or region
  • Formal state designation within country
postal_code
optional
string Postal, zip or rural delivery code, if applicable
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
ewallet
conditional
object Required for type='EWALLET', this contains the necessary information to describe an ewallet payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported eWallets and their channel codes:
  • Indonesia
    • DANA
    • OVO
    • LINKAJA
    • ASTRAPAY
    • JENIUSPAY
    • SHOPEEPAY
  • Philippines
    • SHOPEEPAY
    • GRABPAY
    • PAYMAYA
    • GCASH
  • Vietnam
    • APPOTA
    • MOMO
    • ZALOPAY
    • VNPTWALLET
    • SHOPEEPAY
    • VIETTELPAY
  • Thailand
    • WECHATPAY
    • LINEPAY
    • SHOPEEPAY
    • TRUEMONEY
  • Malaysia
    • TOUCHNGO
    • SHOPEEPAY
    • GRABPAY
channel_properties
required
object Object that contains the required information to perform payments with eWallet account

OVO (ONE_TIME_USE) required fields
Key Value
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.

DANA (ONE_TIME_USE), LINKAJA (ONE_TIME_USE), SHOPEEPAY (ONE_TIME_USE) (ID, PH, TH & MY), ASTRAPAY (ONE_TIME_USE), GCASH (ONE_TIME_USE), WECHATPAY, LINEPAY, TRUEMONEY (ONE_TIME_USE), TOUCHNGO (ONE_TIME_USE), GRABPAY (PH & MY) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful

SHOPEEPAY (ONE_TIME_USE) (VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY (ONE_TIME_USE) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
pending_return_url
required
string URL where the end-customer is redirected if the authorization is pending

GRABPAY (PH & MY), OVO (MULTIPLE_USE), DANA (MULTIPLE_USE), LINKAJA (MULTIPLE_USE), SHOPEEPAY (MULTIPLE_USE) (ID, PH & MY), ASTRAPAY (MULTIPLE_USE), GCASH (MULTIPLE_USE), TOUCHNGO (MULTIPLE_USE) fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed

MAYA (PAYMAYA) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
required
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.

JENIUSPAY required fields
Key Value
cashtag
required
string Cashtag of the funding source
For GRABPAY (MY):
Key Value
allowed_payment_options
nullable
Array of enums
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Usage for each Payment method reusability
  • ONE_TIME_USE - Choose which payment option to show, default will show all. To hide all payment options, use empty Array []. Ewallat balance option will always visible.
  • MULTIPLE_USE - Choose One payment option to use, default will use GrabPay Ewallet balance

direct_debit
conditional
object Required for type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported banks and their channel codes:
  • Indonesia
    • BRI
    • MANDIRI
  • Philippines
    • BPI
    • BPI_RECURRING
    • UBP
    • UBP_EADA
    • RCBC
    • CHINABANK

  • Thailand
    • SCB
    • KTB
    • BBL
    • BAY

  • Malaysia
channel_properties
required
object Object that contains the required information to perform payments using direct debit

BRI Direct Debit required fields
Key Value
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
card_last_four
required
string Last four digits of the debit card
card_expiry
optional
string Expiry month and year of the debit card (in MM/YY format)
email
required
string Email address of the customer that is registered to the partner channel

MANDIRI, BPI, UBP, RCBC, CHINABANK, and FPX Channels under Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
SCB and BBL Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
KTB and BAY Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.

card
conditional
object For type='CARD', this contains the necessary information to describe a Card payment method. This will be null otherwise.
Key Value
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • USD
channel_properties
required
object Information provided specific to the channel partner that was provided during the request
Key Value
skip_three_d_secure
conditional
boolean This field value is only configurable for reusability = MULTIPLE_USE to indicate whether to perform 3DS during the linking phase.
Defaults to false
cardonfile_type
conditional
string Type of โ€œcredential-on-fileโ€ / โ€œcard-on-fileโ€ / COF payment for subsequent usage. Indicates future card-on-file usage.
If you intend for a card to be used for future COF transactions, then this value must be included so that Xendit can inform the processors of this setup, and then after that on every transaction following the first transaction.
Default: CUSTOMER_UNSCHEDULED
Possible values:
  • CUSTOMER_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments that do not follow a schedule.
    Example: simple โ€œsave card for future checkoutโ€ eCommerce flow, the future payments would always be CUSTOMER_UNSCHEDULED
  • MERCHANT_UNSCHEDULED - If you intend to use this Payment Method to perform future COF payments initiated without customer interaction and do not follow a schedule
    Example: auto top-up payment flow
  • RECURRING - If you intend to use this Payment Method to process a series of transactions at fixed, regular intervals.
    Example: Subscriptions

Notes: In order to process MERCHANT_UNSCHEDULED and RECURRING card-on-file transaction types:
  • Aggregator Merchant will need to be allowed to perform transaction without 3DS, please check this guide for self-serve or contact Xendit representative for enabling 3DS as optional
  • Switcher Merchant with their own acquiring bank MID will need to have MID for non 3DS transactions and support recurring configured by the acquirer.
success_return_url
conditional
string URL where the end-customer is redirected if the linking is successful.
Required when skip_three_d_secure = false.
This will be null if not applicable.
failure_return_url
conditional
string URL where the end-customer is redirected if the linking has failed.
Required when skip_three_d_secure = false.
This will be null if not applicable.
card_information
required
object Information pertaining to the actual card
Key Value
card_number
required
string Full card number (Only for PCI-DSS compliant merchants)
expiry_month
required
string Card expiry month in MM format. (Only for PCI-DSS compliant merchants)
expiry_year
required
number Card expiry year in YY format. (Only for PCI-DSS compliant merchants)
cardholder_name
required
number Cardholder's name. Issuer will use this information to assess the transaction.
character: Alphanumeric. No special characters are allowed.
cardholder_email
required
string Card holder's email address. Issuer will use this information to assess the transaction.
cardholder_phone_number
required
string Card holder's phone number or mobile number. Issuer will use this information to assess the transaction.
character: use +(country_code) as prefix. No - and/or blank space is allowed. Follow ITU-E.164 Standard
over_the_counter
conditional
object Required for type='OVER_THE_COUNTER', this contains the necessary information to describe an over-the-counter payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported over-the-counter channels and their respective codes:
  • Indonesia
    • ALFAMART
    • INDOMARET
  • Philippines
    • 7ELEVEN
    • 7ELEVEN_CLIQQ
    • CEBUANA
    • ECPAY
    • PALAWAN
    • MLHUILLIER
    • DRAGONLOAN_ECPAY
    • SM_BILLS
    • ROBINSONS_BILLS

currency
optional
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
amount
optional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding payment code will accept any amount as payment (open amount).
channel_properties
required
object Object that contains the information to generate a valid payment code

Key Value
customer_name
required
string Complete name of the payor. May be used by the channel partner to verify their identity. Must contain letters and space only.
payment_code
optional
string The payment code that you want to assign, e.g 12345. If none is provided, one will be generated at random.

Default: 8 random alphanumeric characters

Note: Do not include your prefix on this field.
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the payment code will be expired.

Default: The default validity period will be 31 years for Indonesian channels and 2 days for Philippine channels from creation date.

Note: The minimum is 2 hours and the maximum is 9 days for 7ELEVEN
virtual_account
conditional
object Required for type='VIRTUAL_ACCOUNT', this contains the necessary information to describe a virtual account payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported virtual account channels and their respective codes:
  • Indonesia
    • BCA
    • BSI
    • BJB
    • CIMB
    • SAHABAT_SAMPOERNA
    • ARTAJASA
    • BRI
    • BNI
    • MANDIRI
    • PERMATA
currency
optional
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
amount
optional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.

If amount is not provided, the corresponding virtual account will accept any amount as payment (open amount).
channel_properties
required
object Object that contains the information to generate a valid payment code

Key Value
customer_name
required
string Complete name of the payor. May be used by the channel partner to verify their identity. Must contain letters and space only.
virtual_account_number
optional
string You may assign a specific Virtual Account number using this parameter. If you do not send one, one will be picked at random.
Make sure the number you specify is within your Virtual Account range.
suggested_amount
optional
number The suggested amount you want to be displayed on the partner channel's platform

Note: Suggested amount is the amount that can seen as a suggestion, but user can still put any number (only supported for MANDIRI and BRI)
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the virtual account number will be expired.

Default: The default expiration date will be 31 years from creation date.
qr_code
conditional
object Required for type='QR_CODE', this contains the necessary information to describe a QR Code payment method.

Key Value
channel_code
conditional
string QR payments standard used in generating the QR code. Channel_code is not required for Indonesia country.
  • Indonesia
    • DANA
    • LINKAJA
  • Thailand
    • PROMPTPAY

currency
optional
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • THB
amount
conditional
number Expected and accepted amount of the transaction in the actual value in the provided currency. Requied if the Reusability is ONE_TIME_USE.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.

If amount is not provided, the corresponding QR Code will accept any amount as payment (open amount).

Create Payment Method Response

Example Create Payment Method Success Response

{
  "id": "pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39",
  "type": "EWALLET",
  "reusability": "MULTIPLE_USE",
  "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "status": "REQUIRES_ACTION",
  "country": "ID",
  "actions": [
    {
      "action": "AUTH",
      "url_type": "WEB",
      "url": "https://link-web.xendit.co/oauth/user_redirection_url",
      "method": "GET"
    }
  ],
  "ewallet": {
    "channel_code": "OVO",
    "channel_properties": {
      "success_return_url": "https://your-redirect-website.com/success",
      "failure_return_url": "https://your-redirect-website.com/failure"
    },
    "account": {
      "account_details": "+62*****3123",
      "name": null,
      "balance": 123456,
      "point_balance": 123456
    }
  },
  "qr_code": null,
  "created": "2020-08-29T09:12:33.001Z",
  "updated": "2020-08-29T09:12:33.001Z",
  "metadata": {
    "sku": "iPixel phone - 123xa2"
  }
}

A successful Payment Method creation returns a Payment Method Object with an HTTP 201 status code.

Create Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
VA_NUMBER_OUT_OF_RANGE
400
The provided virtual_account_number is out of the merchant's range
INVALID_API_KEY
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details. If you provide customer object request, the reference_id of customer object may already exist.
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer

Update Payment Method

This endpoint is used to update specific information of a particular payment method.

Endpoint: Update Payment Method

PATCH https://api.xendit.co/v2/payment_methods/:id

Update Payment Method Request

Example Update Payment Method Request

curl https://api.xendit.co/v2/payment_methods/pm-4c85fd2c-29da-4bc4-b642-064a42727d89 -X PATCH \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "over_the_counter": {
        "channel_properties": {
          "expires_at": "2022-08-29T09:12:33.001Z",
        }
      },
}' \
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.
Request Body Parameter Type Description
reference_id
optional
string Merchant-provided identifier for this payment method.

For OVER_THE_COUNTER, QR_CODE, and VIRTUAL_ACCOUNT, this will be extended to the actual payments made.
Maximum length: 255 characters
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
status
optional
object Desired new status of the payment method. This is used for temporarily disable/enable a certain payment method. Only toggle from ACTIVE to INACTIVE and vice versa is supported.
reusability
optional
object Only supported for select VIRTUAL_ACCOUNT channels.
Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.
Accepted values:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
  • MULTIPLE_USE - Payment method is tokenized and may be reused for subsequent payments.
over_the_counter
optional
object For type='OVER_THE_COUNTER', the following properties may be updated:

Key Value
amount
optional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding payment code will accept any amount as payment (open amount).
channel_properties
optional
object Object that contains the information to generate a valid payment code

Key Value
customer_name
optional
string Complete name of the payor. May be used by the channel partner to verify their identity. Must contain letters and space only.
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the payment code will be expired.

Default: The default validity period will be 31 years for Indonesian channels and 2 days for Philippine channels from creation date.

Note: The minimum is 2 hours and the maximum is 9 days for 7ELEVEN
virtual_account
optional
object For type='VIRTUAL_ACCOUNT', the following properties may be updated:

Key Value
amount
optional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.

If amount is not provided, the corresponding virtual account will accept any amount as payment (open amount).
channel_properties
optional
object Object that contains the information to generate a valid payment code

Key Value
suggested_amount
optional
number The suggested amount you want to be displayed on the partner channel's platform

Note: Suggested amount is the amount that can seen as a suggestion, but user can still put any number (only supported for MANDIRI and BRI)
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the virtual account number will be expired.

Default: The default expiration date will be 31 years from creation date.

Update Payment Method Response

Example Update Payment Method Response

{
  "id": "pm-4c85fd2c-29da-4bc4-b642-064a42727d89",
  "type": "OVER_THE_COUNTER",
  "reusability": "MULTIPLE_USE",
  "customer_id": null,
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "status": "PENDING",
  "country": "PH",
  "description": null,
  "actions": [],
  "ewallet": null,
  "direct_debit": null,
  "over_the_counter": {
    "channel_code": "7ELEVEN_CLIQQ",
    "currency": "PHP",
    "amount": 1000,
    "channel_properties": {
      "customer_name": "John Doe",
      "payment_code": "12345678",
      "expires_at": "2022-08-29T09:12:33.001Z"
    }
  },
  "virtual_account": null,
  "qr_code": null,
  "reference_id": "371d8a6e-587c-4789-bea5-fac4319b2409",
  "created": "2020-08-29T09:12:33.001Z",
  "updated": "2020-08-29T09:12:33.001Z"
}

The updated Payment Method Object with an HTTP 200 status code.

Update Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
INVALID_API_KEY
401
API key format is invalid
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

Expire Payment Method

This API is used to force expiry or revoke authorization to an active payment method. For VIRTUAL_ACCOUNT and OVER_THE_COUNTER, this will also set the expires_at to the time the expiration request was made. For DIRECT_DEBIT with KTB as channel_code, required confirmation from end users.

Endpoint: Expire Payment Method

POST https://api.xendit.co/v2/payment_methods/:id/expire

Endpoint: Expire Direct Debit KTB Payment Method

POST https://api.xendit.co/v2/payment_methods/:id/expire?success_return_url=https://your-redirect-website.com/success&failure_return_url=https://your-redirect-website.com/failure

Expire Payment Method Request

Example Expire Payment Method Request

curl https://api.xendit.co/v2/payment_methods/pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a/expire -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.
Query String Parameter Type Description
success_return_url string URL where the end customer is redirected if the unlinking authorization is successful. Required if the payment method is direct debit and the channel is KTB.
failure_return_url string URL where the end customer is redirected if the unlinking authorization is failed. Required if the payment method is direct debit and the channel is KTB.

Expire Payment Method Response

Example Expire Payment Method Success Response

{
    "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
    "card": null,
    "type": "DIRECT_DEBIT",
    "status": "EXPIRED",
    "actions": [],
    "country": "PH",
    "created": "2022-08-12T13:30:26.579048Z",
    "ewallet": null,
    "qr_code": null,
    "updated": "2022-08-12T13:30:58.908220358Z",
    "metadata": null,
    "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
    "description": null,
    "reusability": "MULTIPLE_USE",
    "direct_debit": {
        "type": "BANK_ACCOUNT",
        "debit_card": null,
        "bank_account": {
            "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
            "masked_bank_account_number": "XXXXXX1234"
        },
        "channel_code": "BPI",
        "channel_properties": {
            "failure_return_url": "https://your-redirect-website.com/failure",
            "success_return_url": "https://your-redirect-website.com/success"
        }
    },
    "failure_code": null,
    "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
    "virtual_account": null,
    "over_the_counter": null,
    "billing_information": null,
    "direct_bank_transfer": null,
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Example Expire Direct Debit KTB Payment Method REQUIRES_ACTION Response

{
    "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485b",
    "card": null,
    "type": "DIRECT_DEBIT",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://link-web.xendit.co/oauth/lat-aa620619-124f-41db-995b-66a52abe036a/confirm_unlink",
            "url_type": "WEB",
            "method": "GET"
        }
    ],
    "country": "TH",
    "created": "2022-08-12T13:30:26.579048Z",
    "ewallet": null,
    "qr_code": null,
    "updated": "2022-08-12T13:30:58.908220358Z",
    "metadata": null,
    "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
    "description": null,
    "reusability": "MULTIPLE_USE",
    "direct_debit": {
        "type": "BANK_ACCOUNT",
        "debit_card": null,
        "bank_account": {
            "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
            "masked_bank_account_number": "XXXXXX1234"
        },
        "channel_code": "KTB",
        "channel_properties": {
            "failure_return_url": "https://your-redirect-website.com/failure",
            "success_return_url": "https://your-redirect-website.com/success",
            "mobile_number": "",
            "identity_document_number": ""
        }
    },
    "failure_code": null,
    "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8b",
    "virtual_account": null,
    "over_the_counter": null,
    "billing_information": null,
    "direct_bank_transfer": null,
    "business_id": "5f27a14a9bf05c73dd040bc9"
}

Returns a Payment Method Object with an HTTP 200 status code.

Expire Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
INVALID_API_KEY
401
API key format is invalid
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

Get Payment Method by ID

This endpoints returns the corresponding Payment Method that matches the provided ID.

Endpoint: Get Payment Method by ID

GET https://api.xendit.co/v2/payment_methods/:id

Get Payment Method Request

Example Get Payment Method by ID Request

curl https://api.xendit.co/v2/payment_methods/pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' 
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.

Get Payment Method by ID Response

Example Get Payment Method by ID Response

{
  "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
  "card": null,
  "type": "DIRECT_DEBIT",
  "status": "ACTIVE",
  "actions": [],
  "country": "ID",
  "created": "2022-08-12T13:30:26.579048Z",
  "ewallet": null,
  "qr_code": null,
  "updated": "2022-08-12T13:30:58.908220358Z",
  "metadata": null,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "description": null,
  "reusability": "MULTIPLE_USE",
  "direct_debit": {
      "type": "DEBIT_CARD",
      "debit_card": {
          "mobile_number": "+62818555988",
              "card_last_four": "8888",
              "card_expiry": "06/24",
              "email": "email@email.com"
      },
      "bank_account": null,
      "channel_code": "BRI",
      "channel_properties": {
          "mobile_number": "+62818555988",
          "card_last_four": "8888",
          "card_expiry": "06/24",
          "email": "test.email@xendit.co"
      }
  },
  "failure_code": null,
  "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
  "virtual_account": null,
  "over_the_counter": null,
  "billing_information": null,
  "direct_bank_transfer": null,
  "business_id": "5f27a14a9bf05c73dd040bc8"
}

A successful Payment Method retrieval returns the matching Payment Method Object with an HTTP 200 status code.

Get Payment Method by ID Errors

Error Code Description
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue

List Payment Methods

This endpoints returns a list of matching Payment Method objects based on the provided query.

Each unique query string parameter is AND operator to each other.

Endpoint: List Payment Methods

GET https://api.xendit.co/v2/payment_methods

List Payment Methods Request

Example List Payment Methods Request by Reference ID and Customer ID

curl https://api.xendit.co/v2/payment_methods?reference_id=620b9df4-fe69-4bfd-b9d4-5cba6861db8a&customer_id=e2878b4c-d57e-4a2c-922d-c0313c2800a3 -X GET \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \ \
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Query String Parameter Type Description
type
optional
string Type of payment method
Accepted values:
  • CARD
  • EWALLET
  • DIRECT_DEBIT
  • OVER_THE_COUNTER
  • QR_CODE
  • VIRTUAL_ACCOUNT
reusability
optional
string Describes whether or not the payment method can be reused for subsequent payments.

For VIRTUAL_ACCOUNT, OVER_THE_COUNTER, and QR_CODE, this determines whether or not the payment instrument says valid after a successful payment is made.

For CARD, EWALLET, and DIRECT_DEBIT, this determines whether or not authentication is performed again for subsequent payments.

Accepted values:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
  • MULTIPLE_USE - Payment method is tokenized and may be reused for subsequent payments.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.

For OVER_THE_COUNTER, QR_CODE, and VIRTUAL_ACCOUNT, this will be extended to the actual payments made.
customer_id
optional
string ID of the customer object to which the account token will be linked to.
limit
optional
number Maximum number of resources to be returned in the response. Use after_id and before_id to navigate to other resources.
Default: 10
after_id
optional
string Retrieve all resources created after the provided after_id
before_id
optional
string Retrieve all resources created before the provided before_id

List Payment Methods Response

Example List Payment Methods Response

{
  "data": [
      {
        "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "ACTIVE",
        "actions": [],
        "country": "ID",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:58.908220358Z",
        "metadata": null,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "DEBIT_CARD",
            "debit_card": {
                "mobile_number": "+62818555988",
                    "card_last_four": "8888",
                    "card_expiry": "06/24",
                    "email": "email@email.com"
            },
            "bank_account": null,
            "channel_code": "BRI",
            "channel_properties": {
                "mobile_number": "+62818555988",
                "card_last_four": "8888",
                "card_expiry": "06/24",
                "email": "test.email@xendit.co"
            }
        },
        "failure_code": null,
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null,
        "business_id": "5f27a14a9bf05c73dd040bc8"
    }
  ],
  "has_more": false
}
Body Parameter Type Description
data
required
array of objects Returns an array of matching Payment Method Objects. Returns empty array when there is no result.
has_more
required
boolean Indicates whether there are more items to be queried with after_id of the last item from the current result.

List Payment Methods Errors

Error Code Description
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue

List Payments by Payment Method ID

This endpoints returns a list of matching Payment objects made on a Payment Method.

Each unique query string parameter is AND-ed to each other.

Endpoint: List Payments by Payment Method ID

GET https://api.xendit.co/v2/payment_methods/:id/payments

List Payments by Payment Method ID Request

Example List Payments by Payment Method ID Request

curl https://api.xendit.co/v2/payment_methods/pm-a327c780-66f0-4eb0-aa92-277afdf777c6/payments -X GET \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' 
Header Type Description
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.
Query String Parameter Type Description
payment_request_id
optional
string Retrieve payments made via this payment_request_id
reference_id
optional
string Retrieve payments that match the provided reference_id
status
optional
string Retrieve payments with the provided status
Accepted values:
  • SUCCEEDED
  • FAILED
  • PENDING
limit
optional
number Maximum number of resources to be returned in the response. Use after_id and before_id to navigate to other resources.
Default: 10
after_id
optional
string Retrieve all resources created after the provided after_id
before_id
optional
string Retrieve all resources created before the provided before_id
created[gte]
optional
string Retrieve all resources created after or on the the provided UTC+0 ISO 8601 timestamp
created[lte]
optional
string Retrieve all resources created before or on the the provided UTC+0 ISO 8601 timestamp
updated[gte]
optional
string Retrieve all resources updated after or on the the provided UTC+0 ISO 8601 timestamp
updated[lte]
optional
string Retrieve all resources updated before or on the the provided UTC+0 ISO 8601 timestamp

List Payments by Payment Method ID Response

Example List Payments by Payment Method ID Success Response

{
  "data": [
      {
        "id": "qrpy_0de1622b-677c-48c5-ac8c-ea1b9636c48f",
        "amount": 10000,
        "status": "SUCCEEDED",
        "channel_properties": null,
        "country": "ID",
        "created": "2022-09-22T09:05:29.649418Z",
        "currency": "IDR",
        "customer_id": null,
        "description": null,
        "failure_code": null,
        "metadata": null,
        "payment_method": {
            "type": "QR_CODE",
            "card": null,
            "description": null,
            "direct_bank_transfer": null,
            "direct_debit": null,
            "ewallet": null,
            "id": "pm-a327c780-66f0-4eb0-aa92-277afdf777c6",
            "metadata": null,
            "over_the_counter": null,
            "qr_code": {
                "amount": 10000,
                "channel_code": "QRIS",
                "channel_properties": {
                "qr_string": "some-random-qr-string"
                },
                "currency": "IDR"
            },
            "reference_id": "a4486137-7624-4b34-b879-16cbbfc1a032",
            "reusability": "ONE_TIME_USE",
            "status": "EXPIRED",
            "virtual_account": null,
            "created": "2022-09-22T09:03:39.197475Z",
            "updated": "2022-09-22T09:03:39.197475Z"
        },
        "payment_request_id": "pr-b33ecb15-c8e6-455c-9b1b-84612b6fd13b",
        "reference_id": "a4486137-7624-4b34-b879-16cbbfc1a032",
        "created": "2022-09-22T09:05:30.452Z",
        "updated": "2022-09-22T09:05:29.649418Z"
    }
  ],
  "has_more": false,
  "links": [
    {
      "href": "/v2/payment_methods/pm-a327c780-66f0-4eb0-aa92-277afdf777c6/payments",
      "rel": "first",
      "method": "GET"
    }
  ]
}
Body Parameter Type Description
data
required
array of objects Returns an array of matching Payment Objects. Returns empty array when there is no result.
has_more
required
boolean Indicates whether there are more items to be queried with after_id of the last item from the current result.
links
optional
object The links to the next page based on HATEOAS if there is next result.
The HATEOAS format are:
href: URI of target, this will be to the next link.
rel: The relationship between source and target. The value will be next.
method: The HTTP method, the value will be GET.

List Payment Methods Errors

Error Code Description
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue

API Webhooks

Payment Succeeded

This callback is triggered when a payment is successfully received on a OVER_THE_COUNTER, VIRTUAL_ACCOUNT or QR_CODE payment method.

This is also send for successful Payment Requests for EWALLET, DIRECT_DEBIT, and CARD.

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "event": "payment.succeeded",
    "data": {
        "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
        "amount": 1000,
        "status": "SUCCEEDED",
        "country": "PH",
        "created": "2022-08-12T13:30:40.9209Z",
        "updated": "2022-08-12T13:30:58.729373Z",
        "currency": "PHP",
        "metadata": {
            "sku": "ABCDEFGH"
        },
        "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
        "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
        "payment_method": {
            "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
            "card": null,
            "type": "DIRECT_DEBIT",
            "status": "ACTIVE",
            "created": "2022-08-12T13:30:26.579048Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2022-08-12T13:30:40.221525Z",
            "metadata": null,
            "description": null,
            "reusability": "MULTIPLE_USE",
            "direct_debit": {
                "type": "BANK_ACCOUNT",
                "debit_card": null,
                "bank_account": {
                    "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                    "masked_bank_account_number": "XXXXXX1234"
                },
                "channel_code": "BPI",
                "channel_properties": {
                    "failure_return_url": "https://your-redirect-website.com/failure",
                    "success_return_url": "https://your-redirect-website.com/success"
                }
            },
            "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
            "virtual_account": null,
            "over_the_counter": null,
            "direct_bank_transfer": null
        },
        "description": null,
        "failure_code": null,
        "payment_detail": null,
        "channel_properties": null,
        "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
    },
    "created": "2022-08-12T13:30:58.986Z",
    "business_id": "5f27a14a9bf05c73dd040bc8",
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Payment Failed

This callback is sent when a pending EWALLET, DIRECT_DEBIT, and CARD has failed.

Note: Make sure that you ONLY have a callback URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate callbacks, DO NOT fill out product-specific sections.

Callback Payload

Example: Payment Failed Callback Payload

{
  "event": "payment.failed",
  "data": {
      "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
      "amount": 1000,
      "status": "FAILED",
      "country": "PH",
      "created": "2022-08-12T13:30:40.9209Z",
      "updated": "2022-08-12T13:30:58.729373Z",
      "currency": "PHP",
      "metadata": {
          "sku": "ABCDEFGH"
      },
      "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
      "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
      "payment_method": {
          "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
          "card": null,
          "type": "DIRECT_DEBIT",
          "status": "ACTIVE",
          "created": "2022-08-12T13:30:26.579048Z",
          "ewallet": null,
          "qr_code": null,
          "updated": "2022-08-12T13:30:40.221525Z",
          "metadata": null,
          "description": null,
          "reusability": "MULTIPLE_USE",
          "direct_debit": {
              "type": "BANK_ACCOUNT",
              "debit_card": null,
              "bank_account": {
                  "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                  "masked_bank_account_number": "XXXXXX1234"
              },
              "channel_code": "BPI",
              "channel_properties": {
                  "failure_return_url": "https://your-redirect-website.com/failure",
                  "success_return_url": "https://your-redirect-website.com/success"
              }
          },
          "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
          "virtual_account": null,
          "over_the_counter": null,
          "direct_bank_transfer": null
      },
      "description": null,
      "failure_code": "INSUFFICIENT_BALANCE",
      "payment_detail": null,
      "channel_properties": null,
      "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
  },
  "created": "2022-08-12T13:30:58.986Z",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.

Payment Error Codes

Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
MAX_OTP_ATTEMPTS_ERROR
The maximum incorrect attempts allowed by the channel has been reached.
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.

Payment Method Activated

This callback is triggered when the E-Wallet or Direct Debit has been successfully linked or when the Virtual Account, QR string, or Over-The-Counter Payment code has been successfully activated and can be used for payments. The event will be sent as payment_method.activated

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{

    "event": "payment_method.activated",
    "data": {
        "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "ACTIVE",
        "actions": [],
        "country": "PH",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:58.908220358Z",
        "metadata": null,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                "masked_bank_account_number": "XXXXXX1234"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            }
        },
        "failure_code": null,
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "created": "2022-08-12T13:30:59.074277334Z",
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

Payment Method Expired

This callback is triggered when the linked E-Wallet or Direct Debit has been unlinked or when the Virtual Account, QR string, or Over-The-Counter Payment code has been expired and can no longer be used for payments. The event will be sent as payment_method.expired

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Expired Callback Payload

{
    "event": "payment_method.expired",
    "data": {
        "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "EXPIRED",
        "actions": [],
        "country": "PH",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:58.908220358Z",
        "metadata": null,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                "masked_bank_account_number": "XXXXXX1234"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            }
        },
        "failure_code": null,
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "created": "2022-08-12T13:30:59.074277334Z",
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.expired
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status EXPIRED

Payment Method Failed

This callback is triggered when a particular Payment Method has failed during authentication/authorization. The event will be sent as payment_method.failed

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Failed Callback Payload

{
    "event": "payment_method.failed",
    "data": {
        "id": "pm-d15e011d8-d238-47f6-8041-4a0fe1cc78f0",
        "type": "CARD",
        "status": "FAILED",
        "card": {
            "currency": "PHP",
            "card_information": {
                "type": "UNKNOWN",
                "issuer": "UNKNOWN",
                "country": "US",
                "network": "VISA",
                "token_id": "7ac5069c3e52ececb8e0d7302002a739",
                "expiry_year": "2023",
                "fingerprint": "bdf256307a23088dbd41cf9668a7c95a",
                "expiry_month": "11",
                "cardholder_name": null,
                "masked_card_number": "450159XXXXXX6146"
            },
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success",
                "skip_three_d_secure": false
            },
            "card_verification_results": {
                "cvv_result": null,
                "three_d_secure": {
                    "eci_code": "07",
                    "three_d_secure_flow": "CHALLENGE",
                    "three_d_secure_result": "FAILED",
                    "three_d_secure_version": "1.0.2",
                    "three_d_secure_result_reason": "REJECTED"
                },
                "address_verification_result": null
            }
        },
        "actions": [],
        "country": "PH",
        "created": "2022-09-06T05:36:09.674547Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-09-06T05:36:26.158740637Z",
        "metadata": {},
        "customer_id": "15e011d8-d238-47f6-8041-4a0fe1cc78f0",
        "description": "Card Failure",
        "reusability": "MULTIPLE_USE",
        "direct_debit": null,
        "failure_code": "AUTHENTICATION_FAILED",
        "reference_id": "ec13dd21-8e14-4a4f-ab0e-727a2b977e50",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "created": "2022-09-06T05:36:26.166166474Z",
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status FAILED. See the Failure Code table below to see the possible values of failure_code.

Payment Method Error Codes

Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.

Refund Succeeded

Xendit notifies your system when a refund is successfully processed via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook Settings in Xendit Dashboard under Unified Refund.

The payment notification will be sent as POST request to the URL you set. Xendit attach x-callback-token header that you can validate against Verification Token in Webhook Settings to verify message authenticity.

Please response back with status 200 immediately. Xendit marks webhook event as failed if there is no response within 30s. When events failed, automatic retry will kick-off for the next 24h. Alternatively, you can resend any event in Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

Learn more about Webhook.

Webhook Payload

Example: Refund Succeeded Webhook Payload

{
  "event": "refund.succeeded",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "created": "2020-08-29T09:12:33.001Z",
  "data": {
    "id": "rfd-6f4a377d-a201-437f-9119-f8b00cbbe857",
    "payment_id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
    "invoice_id": null,
    "amount": 10000,
    "payment_method_type": "DIRECT_DEBIT",
    "channel_code": "BPI",
    "currency": "PHP",
    "status": "SUCCEEDED",
    "reason": "CANCELLATION",
    "reference_id": "b2756a1e-e6cd-4352-9a68-0483aa2b6a2",
    "failure_code": null,
    "refund_fee_amount": null,
    "created": "2020-08-30T09:12:33.001Z",
    "updated": "2020-08-30T09:12:33.001Z",
    "metadata": null
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique webhook token to verify the origin of the webhook

webhook-id
required
string A unique identifier of every webhook to help you to handle double webhook by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - refund.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
data
optional
object Refund Object with status SUCCEEDED

Refund Failed

Xendit notifies your system when a refund is successfully processed via webhook. You need to provide an URL to receive webhook. Please specify your URL in Webhook Settings in Xendit Dashboard under Unified Refund.

The payment notification will be sent as POST request to the URL you set. Xendit attach x-callback-token header that you can validate against Verification Token in Webhook Settings to verify message authenticity.

Please response back with status 200 immediately. Xendit marks webhook event as failed if there is no response within 30s. When events failed, automatic retry will kick-off for the next 24h. Alternatively, you can resend any event in Webhook tab at anytime. You can also receive notification via email every 6h to check your webhook health.

Learn more about Webhook.

Webhook Payload

Example: Refund Failed Webhook Payload

{
  "event": "refund.failed",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "created": "2020-08-29T09:12:33.001Z",
  "data": {
    "id": "rfd-fca8d8bc-497c-42a5-b16f-97825323502a",
    "payment_id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
    "invoice_id": null,
    "amount": 10000,
    "payment_method_type": "DIRECT_DEBIT",
    "channel_code": "BPI",
    "currency": "PHP",
    "status": "FAILED",
    "reason": "CANCELLATION",
    "reference_id": "b2756a1e-e6cd-4352-9a68-0483aa2b6a2",
    "failure_code": "DUPLICATE_ERROR",
    "refund_fee_amount": null,
    "created": "2020-08-30T09:12:33.001Z",
    "updated": "2020-08-30T09:12:33.001Z",
    "metadata": null
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique webhook token to verify the origin of the webhook

webhook-id
required
string A unique identifier of every webhook to help you to handle double webhook by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhooks
Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - refund.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for webhook notification creation. Timezone UTC+0.
data
optional
object Refund Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.

Refund Error Codes

Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_FOUND
Destination account for refund was not found
DUPLICATE_ERROR
There's an existing record of refund
INSUFFICIENT_BALANCE
Error because there is no sufficient balance in your Xendit balance to perform the refund
REFUND_FAILED
Refund rejected by the partner channel

Payment Scenario

This section provides the following scenario that can be handled payment Payment Request Scenario :

Direct Debit

Initiate One Time Payment

This flow is designed for scenarios where you want to enable a guest user to make a checkout payment.

After making the following payment, the next task is to verify it using an OTP (One-Time Password). For this flow, you may need to use xendit hosted OTP given in action parameter in the response.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 500,
    "currency": "PHP",
    "payment_method": {
        "type": "DIRECT_DEBIT",
        "direct_debit": {
            "channel_code": "BPI",
            "channel_properties": {
                "success_return_url" : "https://redirect.me/goodstuff",
                "failure_return_url" : "https://redirect.me/badstuff"
            }
        },
        "reusability": "ONE_TIME_USE"
    },
    "customer_id": "cust-1e68806c-38d7-4109-b1cd-4f10ef4cf99b",
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • THB
  • MYR
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

A customer_id is required for all DIRECT_DEBIT payment methods if customer object is null.
customer
conditional
object A customer object to skip Create Customer URL endpoint process. This object is required if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Required for INDIVIDUAL type
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
business_detail
conditional
object JSON object containing details of the business. Required for BUSINESS type
Key Value
business_name
required
string Name of business entity
trading_name
optional
string Brand name or trading name known in market
business_type
required
string Legal entity type of the business
Supported values: CORPORATION,
SOLE_PROPRIETOR,
PARTNERSHIP,
COOPERATIVE,
TRUST,
NON_PROFIT,
GOVERNMENT
nature_of_business
optional
string Free text description of the type of business this entity pursues. Examples are: Ecommerce, Travel
business_domicile
optional
string Registered country of the business

Format ISO 3166-2 Country Code
date_of_registration
optional
string Business registration date

Format YYYY-MM-DD string
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
optional
string 2-letter ISO 3166-2 country code indicating country of transaction.

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
conditional
object Note: Only one of payment_method{} or payment_method_id must be present.
Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.

The parameters to be set for the payment method object
Key Value
type
required
string Type of payment method
For Direct debit:
  • DIRECT_DEBIT
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For DIRECT_DEBIT, this determines whether or not authentication is performed again for subsequent payments.

Accepted values for one time case:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.


description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
direct_debit
required
object Required for type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported banks and their channel codes: refer to this section
channel_properties
required
object Object that contains the required information to perform payments using direct debit

BRI Direct Debit required fields
Key Value
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
card_last_four
required
string Last four digits of the debit card
card_expiry
optional
string Expiry month and year of the debit card (in MM/YY format)
email
required
string Email address of the customer that is registered to the partner channel

MANDIRI, BPI, UBP, RCBC, CHINABANK, and FPX Channels under Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
SCB and BBL Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
KTB and BAY Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.

metadata
optional
object object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490",
    "country": "PH",
    "amount": 500,
    "currency": "PHP",
    "business_id": "6396e6d48c59c18ca0e55218",
    "reference_id": "eeaf6501-dea4-4103-bb7e-8ee706ce04f6",
    "payment_method": {
        "id": "pm-02318afc-9810-4044-b8b4-d0eacb0a77a8",
        "type": "DIRECT_DEBIT",
        "reference_id": "54ee6999-a032-40c6-b731-dcc7f6d26040",
        "description": null,
        "created": "2023-07-16T22:38:13.474210828Z",
        "updated": "2023-07-16T22:38:13.474210828Z",
        "card": null,
        "ewallet": null,
        "direct_debit": {
            "channel_code": "BPI",
            "channel_properties": {
                "success_return_url": "https://redirect.me/goodstuff",
                "failure_return_url": "https://redirect.me/badstuff"
            },
            "type": "BANK_ACCOUNT",
            "bank_account": {
                "masked_bank_account_number": null,
                "bank_account_hash": null
            },
            "debit_card": null
        },
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "ONE_TIME_USE",
        "status": "PENDING"
    },
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    },
    "customer_id": "cust-bf61e185-da02-4223-a594-5da05c45218e",
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-16T22:38:13.231458108Z",
    "updated": "2023-07-16T22:38:13.231458108Z",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://link-web-staging.xendit.co/oauth/lat-17702cc1-31c8-4791-b243-8699a3575146/confirm",
            "url_type": "WEB",
            "method": "GET",
            "qr_code": null
        }
    ],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.


Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • VND - Only supports positive integers.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to complete the payment. Typical actions are for merchant to trigger OTP validation or redirect your customer to an authentication page.
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to complete a payment. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
See possible codes here.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
INSUFFICIENT_BALANCE
400
Source of funds has insufficient balance to complete the transaction.
MAX_AMOUNT_LIMIT_ERROR
400
The transaction amount exceeds the partner channel's set limits.
FORBIDDEN
403
Provided API key does not have the correct permissions to perform the operation.

Validate OTP One Time Payment

This endpoint only applies to BRI Direct Debit. This is used when an additional authorization (ex. OTP Validation) is required in order to successfully activate a payment method. This is equivalent to the POST - AUTH action provided when a Payment Method has the status REQUIRES_ACTION.

Endpoint: Account Linking - Authorize Payment Method

POST https://api.xendit.co/v2/payment_methods/:id/auth

Authorize Payment Method Request

Example Account Linking - Authorize Payment Method Request

curl https://api.xendit.co/v2/payment_methods/pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a/auth -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "auth_code": "356443"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.
Request Body Parameter Type Description
auth_code
required
string The authorization code or OTP inputted by the end-customer.

Authorize Payment Method Response

Example Account Linking - Authorize Payment Method Success Response

{
  "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
  "card": null,
  "type": "DIRECT_DEBIT",
  "status": "ACTIVE",
  "actions": [],
  "country": "ID",
  "created": "2022-08-12T13:30:26.579048Z",
  "ewallet": null,
  "qr_code": null,
  "updated": "2022-08-12T13:30:58.908220358Z",
  "metadata": null,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "description": null,
  "reusability": "MULTIPLE_USE",
  "direct_debit": {
      "type": "DEBIT_CARD",
      "debit_card": {
        "mobile_number": "+62818555988",
            "card_last_four": "8888",
            "card_expiry": "06/24",
            "email": "email@email.com"
      },
      "bank_account": null,
      "channel_code": "BRI",
      "channel_properties": {
          "mobile_number": "+62818555988",
          "card_last_four": "8888",
          "card_expiry": "06/24",
          "email": "test.email@xendit.co"
      }
  },
  "failure_code": null,
  "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
  "virtual_account": null,
  "over_the_counter": null,
  "billing_information": null,
  "direct_bank_transfer": null,
  "business_id": "5f27a14a9bf05c73dd040bc8"
}

Returns a Payment Method Object with an HTTP 200 status code.

Authorize Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
EXPIRED_OTP_ERROR
400
The provided auth_code has expired
INVALID_OTP_ERROR
400
The provided auth_code is incorrect
MAX_OTP_ATTEMPTS_ERROR
400
The maximum attempts allowed by the channel has been reached
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
DATA_NOT_FOUND
404
The provided id did not match any of our records
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
PAYMENT_METHOD_ALREADY_ACTIVE
409
Cannot proceed because the payment method is already active or has been activated
PAYMENT_METHOD_ALREADY_FAILED
409
Cannot proceed because the payment method has failed authorization and cannot be retried
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

Webhook Payment Succeeded Direct Debit One Time

This callback will be sent to you once the payment has been detected from you end-customer.

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "created": "2023-08-07T17:41:00.766Z",
    "business_id": "6396e6d48c59c18ca0e55333",
    "event": "payment.succeeded",
    "data": {
        "id": "ddpy-43f10ddb-dc10-46a7-951c-00f834d2f555",
        "items": null,
        "amount": 500,
        "status": "SUCCEEDED",
        "country": "PH",
        "created": "2023-08-07T17:40:54.452582Z",
        "updated": "2023-08-07T17:41:00.456517Z",
        "currency": "PHP",
        "metadata": {
            "foo": "bar"
        },
        "customer_id": "cust-b103fdf1-8b38-48c5-bbe4-8d70b6efc54r",
        "description": "This is a description.",
        "failure_code": null,
        "reference_id": "ca9a047f-e808-4494-9980-0a49002ac2a2",
        "payment_detail": null,
        "payment_method": {
            "id": "pm-19cc567e-4444-4214-9e77-e4d28f9b5050",
            "card": null,
            "type": "DIRECT_DEBIT",
            "status": "EXPIRED",
            "created": "2023-08-07T17:40:39.115295Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2023-08-07T17:40:53.962941Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": {
                "type": "BANK_ACCOUNT",
                "debit_card": null,
                "bank_account": {
                    "bank_account_hash": "8f06b7dc684aa57a283adf49b2f67bdb11750ac04300f3996d97c7412ac5ca48",
                    "masked_bank_account_number": "XXX1631"
                },
                "channel_code": "BPI",
                "channel_properties": {
                    "failure_return_url": "https://redirect.me/badstuff",
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "reference_id": "39d44d83-e41a-4639-b359-ab2071d7f13a",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-1d72af2f-8bd7-45a8-8d12-7ab23170cf0c"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook Payment Failed Direct Debit One Time

Note: Make sure that you ONLY have a callback URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate callbacks, DO NOT fill out product-specific sections.

Callback Payload

Example: Payment Failed Callback Payload

{
    "created": "2023-08-07T17:49:26.242Z",
    "business_id": "6396e6d48c59c18ca0e552555",
    "event": "payment.failed",
    "data": {
        "id": "ddpy-0c3a5e88-11c5-4b94-a05d-93f8778e3756",
        "items": null,
        "amount": 11001,
        "status": "FAILED",
        "country": "PH",
        "created": "2023-08-07T17:49:25.699261Z",
        "updated": "2023-08-07T17:49:25.753596Z",
        "currency": "PHP",
        "metadata": {
            "foo": "bar"
        },
        "customer_id": "cust-b103fdf1-8b38-48c5-bbe4-8d70b6e33333",
        "description": "This is a description.",
        "failure_code": "MAX_AMOUNT_LIMIT_ERROR",
        "reference_id": "3aba1bc1-aa15-4145-3333-c985c5b3e2ce",
        "payment_detail": null,
        "payment_method": {
            "id": "pm-c6646b5a-a09f-45f3-3333-a4c8394b47e9",
            "card": null,
            "type": "DIRECT_DEBIT",
            "status": "EXPIRED",
            "created": "2023-08-07T17:49:13.51121Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2023-08-07T17:49:25.212213Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": {
                "type": "BANK_ACCOUNT",
                "debit_card": null,
                "bank_account": {
                    "bank_account_hash": "8f06b7dc684aa57a283adf49b2f67bdb11750ac04300f3996d97c7412ac5ca48",
                    "masked_bank_account_number": "XXX1631"
                },
                "channel_code": "BPI",
                "channel_properties": {
                    "failure_return_url": "https://redirect.me/badstuff",
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "reference_id": "311ee56b-7a7a-4445-3333-ac553c970f54",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-f6b0802a-3333-45ee-8b3a-77f1d6d9fc27"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
MAX_OTP_ATTEMPTS_ERROR
The maximum incorrect attempts allowed by the channel has been reached.
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.

E-Wallets

Initiate One Time Payment

This endpoint provides the endpoint to create charge for Ewallet One time use. This scenario is suitable for Merchant who implement checkout case using Ewallet.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "currency": "IDR",
    "amount": 100000,
    "payment_method": {
        "type": "EWALLET",
        "reusability": "ONE_TIME_USE",
        "ewallet": {
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "success_return_url": "https://your-redirect-website.com/success"
            }
        }
    },
    "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde",
    "metadata": {
        "sku": "ABCDEFGH"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • VND
  • THB
  • MYR
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • VND - Only supports positive integers.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

A customer_id is required for all Ewallet payment methods if the customer object is null.
customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is required if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • VN - Vietnam
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Note: Only one of payment_method{} or payment_method_id must be present.
Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.
The parameters to be set for the payment method object
Key Value
type
required
string Type of payment method - to use EWALLET as value
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

use ONE_TIME_USE as value for one time payment case for eWallets
reference_id
optional
string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
description
optional
string Free-text field for any additional information regarding the payment method
metadata
optional
string A free-format JSON for additional information that you may use
ewallet
required
object For type='EWALLET', this contains the necessary information to describe an ewallet payment method

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported eWallets and their channel codes can be found in supported channels section
channel_properties
required
object Object that contains the required information to perform payments with eWallet account

OVO required fields
Key Value
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.

DANA, LINKAJA, SHOPEEPAY(ID, PH, TH & MY), ASTRAPAY, GCASH, WECHATPAY (TH), LINEPAY, TRUEMONEY, TOUCHNGO, GRABPAY (PH) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful

MAYA (PAYMAYA) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
required
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes.

JENIUSPAY required fields
Key Value
cashtag
required
string Cashtag of the funding source
SHOPEEPAY(VN), APPOTA, MOMO, ZALOPAY, VNPTWALLET, VIETTELPAY required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
pending_return_url
required
string URL where the end-customer is redirected if the authorization is pending

WECHATPAY (MY) required fields
Key Value
device_type
required
string determines the device type of the end user. Accepts the following values:
  • DESKTOP
  • MOBILE
payer_ip_address
nullable
string The IP address of the end user's client (e.g. 192.168.0.1)
Required if device_type is set to MOBILE
pending_return_url
nullable
string URL where the end-customer is redirected if the authorization is pending
Required if device_type is set to MOBILE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
Required if device_type is set to MOBILE
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization has failed
Required if device_type is set to MOBILE

For GRABPAY (MY):
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
allowed_payment_options
optional
Array of enums
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Default - [PAYLATER_POSTPAID, PAYLATER_INSTALLMENTS_4MO]. Ewallet balance payment option will always be available

metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490",
    "country": "ID",
    "amount": 1500,
    "currency": "IDR",
    "business_id": "628db55f8378fa6f14db977f",
    "reference_id": "bf90f78f-fd9f-4701-9143-ecea0c999af1",
    "payment_method": {
        "id": "pm-9690c507-0caf-4dec-877b-1a52304848f9",
        "type": "EWALLET",
        "reference_id": "d2878b0e-f2bb-4824-8c9c-be1273a446ea",
        "description": null,
        "created": "2023-07-18T02:01:02.620185557Z",
        "updated": "2023-07-18T02:01:02.620185557Z",
        "card": null,
        "ewallet": {
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "success_return_url": "https://redirect.me/goodstuff"
            },
            "account": {
                "name": null,
                "account_details": null,
                "balance": null,
                "point_balance": null
            }
        },
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "ONE_TIME_USE",
        "status": "ACTIVE"
    },
    "description": null,
    "metadata": null,
    "customer_id": null,
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-18T02:01:02.646818745Z",
    "updated": "2023-07-18T02:01:02.646818745Z",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://ewallet-mock-connector.xendit.co/v1/ewallet_connector/checkouts?token=ciqv4nkabidq0em86ofg",
            "url_type": "DEEPLINK",
            "method": "GET",
            "qr_code": null
        },
        {
            "action": "PRESENT_TO_CUSTOMER",
            "url": null,
            "url_type": null,
            "method": null,
            "qr_code": "test-qr-string"
        }
    ],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.


Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • VND
  • THB
  • MYR
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • VND - Only supports positive integers.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to complete the payment. Typical actions are for merchant to trigger OTP validation or redirect your customer to an authentication page.
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to complete a payment. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
See possible codes here.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
PROCESSOR_CONFIGURATION_ERROR
500
Payment declined due to a problem with the merchant configuration on the Card Processor. Contact Xendit to troubleshoot the issue.
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
INSUFFICIENT_BALANCE
400
Source of funds has insufficient balance to complete the transaction
MAX_AMOUNT_LIMIT_ERROR
400
The transaction amount exceeds the partner channel's set limits
INVALID_PAYMENT_METHOD
400
The provided payment method id has already expired or is inactive
ACCOUNT_NOT_ACTIVATED
400
End-customer's account is not activated for payments.

Webhook Payment Succeeded Ewallet One Time

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "created": "2023-05-31T08:18:13.473Z",
    "business_id": "628db55f8378fa6f14db977f",
    "event": "payment.succeeded",
    "data": {
        "id": "ewc_f545a7d9-482b-4eb0-b175-032252d3acca",
        "items": null,
        "amount": 1500,
        "status": "SUCCEEDED",
        "country": "ID",
        "created": "2023-05-31T08:17:40.193463Z",
        "updated": "2023-05-31T08:18:13.042335Z",
        "currency": "IDR",
        "metadata": null,
        "customer_id": null,
        "description": null,
        "failure_code": null,
        "reference_id": "8346c97c-6c16-4745-a1b4-69656f0b2d4e",
        "payment_detail": {
            "fund_source": "1_MONTH_INSTALLMENT",
            "source": "Shopeepay"
        },
        "payment_method": {
            "id": "pm-62e521fc-09bd-4d50-bc44-a190c482a1a5",
            "card": null,
            "type": "EWALLET",
            "status": "EXPIRED",
            "created": "2023-05-31T08:17:40.084679Z",
            "ewallet": {
                "account": {
                    "name": null,
                    "balance": null,
                    "point_balance": null,
                    "account_details": null
                },
                "channel_code": "SHOPEEPAY",
                "channel_properties": {
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "qr_code": null,
            "updated": "2023-05-31T08:17:40.084679Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": null,
            "reference_id": "6c8ad38e-2925-44c4-95af-35003298eefa",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-dd5e558f-1001-4402-84c3-df4375c6b29f"
    },
    "api_version": null
}{
    "created": "2023-05-31T08:18:13.473Z",
    "business_id": "628db55f8378fa6f14db977f",
    "event": "payment.succeeded",
    "data": {
        "id": "ewc_f545a7d9-482b-4eb0-b175-032252d3acca",
        "items": null,
        "amount": 1500,
        "status": "SUCCEEDED",
        "country": "ID",
        "created": "2023-05-31T08:17:40.193463Z",
        "updated": "2023-05-31T08:18:13.042335Z",
        "currency": "IDR",
        "metadata": null,
        "customer_id": null,
        "description": null,
        "failure_code": null,
        "reference_id": "8346c97c-6c16-4745-a1b4-69656f0b2d4e",
        "payment_detail": {
            "fund_source": "1_MONTH_INSTALLMENT",
            "source": "Shopeepay"
        },
        "payment_method": {
            "id": "pm-62e521fc-09bd-4d50-bc44-a190c482a1a5",
            "card": null,
            "type": "EWALLET",
            "status": "EXPIRED",
            "created": "2023-05-31T08:17:40.084679Z",
            "ewallet": {
                "account": {
                    "name": null,
                    "balance": null,
                    "point_balance": null,
                    "account_details": null
                },
                "channel_code": "SHOPEEPAY",
                "channel_properties": {
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "qr_code": null,
            "updated": "2023-05-31T08:17:40.084679Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": null,
            "reference_id": "6c8ad38e-2925-44c4-95af-35003298eefa",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-dd5e558f-1001-4402-84c3-df4375c6b29f"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook Payment Failed Ewallet One Time

Note: Make sure that you ONLY have a callback URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate callbacks, DO NOT fill out product-specific sections.

Callback Payload

Example: Payment Failed Callback Payload

{
    "created": "2023-05-31T10:52:00.666Z",
    "business_id": "628db55f8378fa6f14db9555",
    "event": "payment.failed",
    "data": {
        "id": "ewc_df746164-4f3e-417e-84cd-fa78c1d6a555",
        "items": null,
        "amount": 20111,
        "status": "FAILED",
        "country": "ID",
        "created": "2023-05-31T10:51:48.73712Z",
        "updated": "2023-05-31T10:51:58.057377Z",
        "currency": "IDR",
        "metadata": null,
        "customer_id": null,
        "description": null,
        "failure_code": "ACCOUNT_NOT_ACTIVATED",
        "reference_id": "7ce8f500-1bad-4d46-a1eb-0879b13e1bba",
        "payment_detail": {
            "fund_source": "1_MONTH_INSTALLMENT",
            "source": "Shopeepay"
        },
        "payment_method": {
            "id": "pm-8bfd2cf3-6aca-4a10-ba48-d5c9e303b5df",
            "card": null,
            "type": "EWALLET",
            "status": "EXPIRED",
            "created": "2023-05-31T10:51:48.646147Z",
            "ewallet": {
                "account": {
                    "name": null,
                    "balance": null,
                    "point_balance": null,
                    "account_details": null
                },
                "channel_code": "SHOPEEPAY",
                "channel_properties": {
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "qr_code": null,
            "updated": "2023-05-31T10:51:48.646147Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": null,
            "reference_id": "869776db-5e5a-48dd-b7b3-45b89737e599",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-63df12be-6dc2-4602-ab7a-78d851f0ee06"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.
INVALID_ACCOUNT_DETAILS
The provided details were rejected by the partner channel due to incorrect information.
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel

Virtual Account

Virtual Account - Creation

This endpoint is provided to create random virtual account number or activate specified virtual account number.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 10000,
    "currency": "IDR",
    "description": "description",
    "payment_method": {
        "reference_id": "reference_id-pm-level",
        "reusability": "ONE_TIME_USE",
        "type": "VIRTUAL_ACCOUNT",
        "virtual_account": {
            "channel_code": "BRI",
            "channel_properties": {
                "customer_name": "John Doe",
                "virtual_account_number" : "9999171877",
                "expires_at": "2023-08-11T17:00:00Z"
            },
            "alternative_display_types": [
              "QR_STRING"
            ]
        }
    },
    "reference_id": "reference_id-pr-level"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Request Body Parameter Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • VND
  • THB
  • PHP
  • MYR
amount
optional
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • VND - Only supports positive integers.
  • MYR - Supports up to two decimal places.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding virtual account will accept any amount as payment (open amount).
reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
optional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is only available if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • VN - Vietnam
  • TH - Thailand
  • PH - Philippines
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
conditional
object Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.
The details of parameters is shown here:

Key Value
type
optional
string Type of payment method
For this case: VIRTUAL_ACCOUNT
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For VIRTUAL_ACCOUNT, OVER_THE_COUNTER, and QR_CODE, this determines whether or not the payment instrument stays valid after a successful payment is made.

Accepted values:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
  • MULTIPLE_USE - Payment method is tokenized and may be reused for subsequent payments.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.

For OVER_THE_COUNTER, QR_CODE, and VIRTUAL_ACCOUNT, this will be extended to the actual payments made.

Maximum length: 255 characters
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
virtual_account
conditional
object Required for type='VIRTUAL_ACCOUNT', this contains the necessary information to describe a virtual account payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported virtual account channels and their respective codes:

Supported virtual account and their channel codes can be found in supported channels section
channel_properties
required
object Object that contains the information to generate a valid payment code

Key Value
customer_name
required
string Complete name of the payor. May be used by the channel partner to verify their identity. Must contain letters and space only.
virtual_account_number
optional
string You may assign a specific Virtual Account number using this parameter. If you do not send one, one will be picked at random. For PH multi-use virtual accounts, this must be 10 digits.
Make sure the number you specify is within your Virtual Account range.

Note:This value is ignored for Vietnam and Thailand virtual accounts.
suggested_amount
optional
number The suggested amount you want to be displayed on the partner channel's platform

Note: Suggested amount is the amount that can seen as a suggestion, but user can still put any number (only supported for MANDIRI and BRI)
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the virtual account number will be expired.

Default: The default expiration date will be 31 years from creation date.
alternative_display_types
optional
array of strings Specify alternative display formats to be returned for Virtual Account creation.

Note:This feature is only available for Vietnam virtual accounts at the moment.

Accepted values:
  • QR_STRING

metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-1fe8d4e9-5d32-464b-8df1-1165faf9fa2e",
    "country": "ID",
    "amount": 10000,
    "currency": "IDR",
    "business_id": "628db55f8378fa6f14db977f",
    "reference_id": "reference_id-pr-level",
    "payment_method": {
        "id": "pm-c19b6b05-fb0f-4af7-8029-5416d75f097c",
        "type": "VIRTUAL_ACCOUNT",
        "reference_id": "reference_id-pm-level",
        "description": null,
        "created": "2023-07-18T02:33:23.176204171Z",
        "updated": "2023-07-18T02:33:23.176204171Z",
        "card": null,
        "ewallet": null,
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": {
            "amount": 10000,
            "currency": "IDR",
            "channel_code": "BRI",
            "channel_properties": {
                "customer_name": "John Doe",
                "virtual_account_number": "132819999171877",
                "expires_at": "2023-08-11T17:00:00Z"
            },
            "alternative_displays": [
              {
                "type": "QR_STRING",
                "data": "SAMPLE_QR_DATA"
              }
            ]
        },
        "qr_code": null,
        "metadata": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "ONE_TIME_USE",
        "status": "PENDING"
    },
    "description": "description",
    "metadata": null,
    "customer_id": null,
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-18T02:33:22.313192354Z",
    "updated": "2023-07-18T02:33:22.313192354Z",
    "status": "PENDING",
    "actions": [],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.


Body Parameter Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • VND
  • THB
  • MYR
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • VND - Only supports positive integers.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_API_KEY
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
OPERATION_NOT_ALLOWED
403
Operation being attempted is not supported for the provided payment method type or channel (eg. VA expiration date, VA suggested/expected amount, VA fixed amount) / Auth for the provided payment method ID is not supported .
DUPLICATED_FIXED_PAYMENT_INSTRUMENT
400
Fixed payment instrument is already in use. Please try again with another fixed payment instrument value.

Webhook VA Activated Callback

This callback is triggered when the Virtual Account, QR string, or Fixed payment have has been successfully activated and can be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{
  "id": "pm-faa27710-5005-4d54-aedf-b2beecd2d68a",
  "event": "payment_method.activated",
  "business_id": "5ddb77c8f4177f1ef8a44939",
  "created": "2023-05-26T09:02:03.038153416Z",
  "data": {
    "id": "pm-faa27710-5005-4d54-aedf-b2beecd2d68a",
    "type": "VIRTUAL_ACCOUNT",
    "country": "ID",
    "business_id": "5ddb77c8f4177f1ef8a44939",
    "customer_id": null,
    "reference_id": "sample_test_payment_method",
    "reusability": "ONE_TIME_USE",
    "status": "ACTIVE",
    "actions": [],
    "description": null,
    "created": "2023-05-26T09:02:02.573677Z",
    "updated": "2023-05-26T09:02:02.857607606Z",
    "metadata": null,
    "billing_information": {
      "country": "",
      "street_line1": null,
      "street_line2": null,
      "city": null,
      "province_state": null,
      "postal_code": null
    },
    "failure_code": null,
    "ewallet": null,
    "direct_bank_transfer": null,
    "direct_debit": null,
    "card": null,
    "over_the_counter": null,
    "qr_code": null,
    "virtual_account": {
      "amount": 100000,
      "currency": "IDR",
      "channel_code": "BRI",
      "channel_properties": {
        "customer_name": "John Doe",
        "virtual_account_number": "920019999153641",
        "expires_at": "2054-05-25T17:00:00Z"
      }
    }
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

Simulate Virtual Account Payments (Test Mode)

Simulate Payments API allows you to emulate your customer behavior to pay to your payment request (i.e. Virtual Account, Over-the-counter / Retail Outlet, QR Code) in TEST mode only.

A callback will be sent to your callback URL upon payment completion. Please refer to the callback section for further information about the callback that will be delivered.

Endpoint: Perform Capture Payment

POST https://api.xendit.co/v2/payment_methods/{id}/payments/simulate

Request Parameters

Example Perform Simulate Payment

curl https://api.xendit.co/v2/payment_methods/pm-b264541b-286d-4044-bac0-ace45b158bef/payments/simulate -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 507000
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
Path Parameter Type Description
id
required
string Payment Method ID. This starts with the prefix pm-. You will get this ID from payment request's response in the payment_method object.
Body Parameter Type Description
amount
required
number The amount that needs to be paid. For a close amount case, the amount must be the expected amount stated in the payment request.

Response Parameters


Body Parameter Type Description
status
required
string The status of the request. If it successfully being processed then the status will be PENDING.
message
required
string Additional information regarding the payment simulation process

Example Simulate Payment Success Response

{
   "status": "PENDING",
   "message": "We're processing payment for payment method ID [pm-xxx] and will send you the result via callback. Please make sure you've set a callback URL in "Payment Succeeded" section in Callback settings in Xendit Dashboard. If you don't receive the callback within the next 5 minutes, please contact us."
}

Error Codes

Error Code Description
INCORRECT_AMOUNT
400
Incorrect amount. The expected amount for this payment method is xxxx.
INACTIVE_PAYMENT_METHOD
400
Could not pay callback {payment method} that is inactive
API_VALIDATION_ERROR
400
There is invalid input in one of the required request fields
PAYMENT_METHOD_NOT_SUPPORTED
400
Simulate Payment API supports VA, OTC, and QR Payment Method. Please try again using VA/OTC/QR Payment Method ID.
REQUEST_FORBIDDEN_ERROR
403
Simulate Payment API cannot be accessed using Live API Key. Please try again using Test API Key and Payment Method ID.
INVALID_API_KEY
401
API key format is invalid.
DATA_NOT_FOUND
404
Provided payment_method_id is invalid, not found or access is unauthorized.
SERVER_ERROR
500
An unexpected error occured. Our team has been notified and will troubleshoot the issue

Webhook VA Payment Succeeded Callback

Callback Payload

Example: Payment Succeeded Callback Payload

{
  "created": "2023-05-29T09:56:05.519Z",
  "business_id": "5ddb77c8f4177f1ef8a44555",
  "event": "payment.succeeded",
  "api_version": null,
  "data": {
    "amount": 100000,
    "channel_properties": null,
    "country": "ID",
    "created": "2023-05-29T09:56:01.205Z",
    "currency": "IDR",
    "customer_id": null,
    "description": null,
    "failure_code": null,
    "id": "647476b1fe87ba392f68d5ec",
    "items": null,
    "metadata": {
      "sku": "ABCDEFGH"
    },
    "payment_detail": null,
    "payment_method": {
      "billing_information": {
        "city": null,
        "country": "",
        "postal_code": null,
        "province_state": null,
        "street_line1": null,
        "street_line2": null
      },
      "card": null,
      "created": "2023-05-29T09:52:35.963186Z",
      "description": null,
      "direct_bank_transfer": null,
      "direct_debit": null,
      "ewallet": null,
      "id": "pm-56752735-91be-4af7-a52a-1d04ef6e0555",
      "metadata": null,
      "over_the_counter": null,
      "qr_code": null,
      "reference_id": "pm-level-39b161ee-9761-5555-b3a5-b8dfcddc3763",
      "reusability": "ONE_TIME_USE",
      "status": "EXPIRED",
      "type": "VIRTUAL_ACCOUNT",
      "updated": "2023-05-29T09:52:36.285346Z",
      "virtual_account": {
        "amount": 100000,
        "channel_code": "BRI",
        "channel_properties": {
          "customer_name": "John Doe",
          "expires_at": "2054-05-28T17:00:00Z",
          "virtual_account_number": "920019999718932"
        },
        "currency": "IDR"
      }
    },
    "payment_request_id": "pr-df1017d4-6247-5555-817e-f6140683c528",
    "reference_id": "4c423b6a-2f9d-4b73-5555-a21c34106f8b",
    "status": "SUCCEEDED",
    "updated": "2023-05-29T09:56:01.205Z"
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook VA Expired Callback

This callback is triggered when the Virtual Account has been expired and can no longer be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Expired Callback Payload

{
  "id": "pm-56752735-91be-4af7-a52a-1d04ef6e0de6",
  "event": "payment_method.expired",
  "business_id": "5ddb77c8f4177f1ef8a44939",
  "created": "2023-05-29T09:56:05.653109662Z",
  "data": {
    "id": "pm-56752735-91be-4af7-a52a-1d04ef6e0de6",
    "type": "VIRTUAL_ACCOUNT",
    "country": "ID",
    "business_id": "5ddb77c8f4177f1ef8a44939",
    "customer_id": null,
    "reference_id": "pm-level-39b161ee-9761-4d4e-b3a5-b8dfcddc3763",
    "reusability": "ONE_TIME_USE",
    "status": "EXPIRED",
    "actions": [],
    "description": null,
    "created": "2023-05-29T09:52:35.963186Z",
    "updated": "2023-05-29T09:56:05.424872798Z",
    "metadata": null,
    "billing_information": {
      "country": "",
      "street_line1": null,
      "street_line2": null,
      "city": null,
      "province_state": null,
      "postal_code": null
    },
    "failure_code": null,
    "ewallet": null,
    "direct_bank_transfer": null,
    "direct_debit": null,
    "card": null,
    "over_the_counter": null,
    "qr_code": null,
    "virtual_account": {
      "amount": 100000,
      "currency": "IDR",
      "channel_code": "BRI",
      "channel_properties": {
        "customer_name": "John Doe",
        "virtual_account_number": "920019999718932",
        "expires_at": "2054-05-28T17:00:00Z"
      }
    }
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.expired
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status EXPIRED

QR Code

QR Code Creation

This endpoint is provided to create QR instrument, hence your end customer is able to pay via QR code.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 15000,
    "currency": "IDR",
    "payment_method": {
        "type": "QR_CODE",
        "reusability": "ONE_TIME_USE",
        "qr_code": {
            "channel_properties": {
                "expires_at": "2023-10-25T00:00:00Z"
            }
        }
    },
    "description": "sample description",
    "metadata": {
        "foo": "bar"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • THB
  • PHP
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • THB - Supports up to two decimal places.
  • PHP - Supports up to two decimal places.
Notes:
reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
optional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is only available if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • TH - Thailand
  • PH - Philippines
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
conditional
object Note: Only one of payment_method{} or payment_method_id must be present.
Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.
The details of parameters is shown here:
Parameter Value
type
required
string Type of payment method
Accepted values:
  • QR_CODE
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For VIRTUAL_ACCOUNT, OVER_THE_COUNTER, and QR_CODE, this determines whether or not the payment instrument stays valid after a successful payment is made. MULTIPLE_USE is not available for QRPh currently.

Accepted values:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
  • MULTIPLE_USE - Payment method is tokenized and may be reused for subsequent payments.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.

For OVER_THE_COUNTER, QR_CODE, and VIRTUAL_ACCOUNT, this will be extended to the actual payments made.

Maximum length: 255 characters
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
qr_code
conditional
object Required for type='QR_CODE', this contains the necessary information to describe a QR Code payment method.

Key Value
channel_code
conditional
string QR payments standard used in generating the QR code. Channel_code is not required for Indonesia country.
Supported QR code and their channel codes can be found in qr object section
channel_properties
optional
object Additional properties that can be used to customize the QR creation request.

Key Value
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the QR Payment Request will be expired. Only applies to one time use QR codes and defaults to 48 hours for the DANA and LINKAJA channel if not supplied. QRPH expiry is fixed at 15 minutes.
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-5295461b-d129-4585-8fe7-4434ad402940",
    "country": "ID",
    "amount": 15000,
    "currency": "IDR",
    "business_id": "628db55f8378fa6f14db977f",
    "reference_id": "7ce15f66-3766-497e-b337-9e861ad9655a",
    "payment_method": {
        "id": "pm-9f9b5f25-e655-4393-ac20-16fd8d8e394c",
        "type": "QR_CODE",
        "reference_id": "dd5c7f03-49f2-403f-91d3-c0bd2e205dc1",
        "description": null,
        "created": "2023-07-18T02:43:47.958973578Z",
        "updated": "2023-07-18T02:43:47.958973578Z",
        "card": null,
        "ewallet": null,
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": {
            "amount": 15000,
            "currency": "IDR",
            "channel_code": "LINKAJA",
            "channel_properties": {
                "qr_string": "some-random-qr-string",
                "expires_at": "2023-10-25T00:00:00Z"
            }
        },
        "metadata": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "ONE_TIME_USE",
        "status": "ACTIVE"
    },
    "description": "sample description",
    "metadata": {
        "foo": "bar"
    },
    "customer_id": null,
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-18T02:43:47.923658935Z",
    "updated": "2023-07-18T02:43:47.923658935Z",
    "status": "PENDING",
    "actions": [],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.

Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • THB
  • PHP
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • THB - Supports up to two decimal places.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
status
required
string Status of the payment method.

Possible values:
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_API_KEY
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
OPERATION_NOT_ALLOWED
403
Operation being attempted is not supported for the provided payment method type or channel (eg. VA expiration date, VA suggested/expected amount, VA fixed amount) / Auth for the provided payment method ID is not supported .

Webhook QR Activated Callback

This callback is triggered when the Virtual Account, QR string, or Fixed payment have has been successfully activated and can be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{
  "id": "pm-c10989bf-87d8-4ac4-a20d-94ea40624d93",
  "event": "payment_method.activated",
  "business_id": "5ddb77c8f4177f1ef8a44939",
  "created": "2023-05-31T07:22:47.287497139Z",
  "data": {
    "id": "pm-c10989bf-87d8-4ac4-a20d-94ea40624d93",
    "type": "QR_CODE",
    "country": "ID",
    "business_id": "5ddb77c8f4177f1ef8a44939",
    "customer_id": null,
    "reference_id": "4a148603-b094-4e81-a3e4-5e4e77b6feac",
    "reusability": "MULTIPLE_USE",
    "status": "ACTIVE",
    "actions": [],
    "description": null,
    "created": "2023-05-31T07:22:47.050186525Z",
    "updated": "2023-05-31T07:22:47.050186525Z",
    "metadata": null,
    "billing_information": {
      "country": "",
      "street_line1": null,
      "street_line2": null,
      "city": null,
      "province_state": null,
      "postal_code": null
    },
    "failure_code": null,
    "ewallet": null,
    "direct_bank_transfer": null,
    "direct_debit": null,
    "card": null,
    "over_the_counter": null,
    "qr_code": {
      "amount": null,
      "currency": "IDR",
      "channel_code": "LINKAJA",
      "channel_properties": {
        "qr_string": "some-random-qr-string",
        "expires_at": "2023-10-25T00:00:00Z"
      }
    },
    "virtual_account": null
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

Simulate QR Payment (Test Mode)

Simulate Payments API allows you to emulate your customer behavior to pay to your payment request (i.e. Virtual Account, Over-the-counter / Retail Outlet, QR Code) in TEST mode.

A callback will be sent to your callback URL upon payment completion. Please refer to the callback section for further information about the callback that will be delivered.

Endpoint: Perform Capture Payment

POST https://api.xendit.co/v2/payment_methods/{id}/payments/simulate

Request Parameters

Example Perform Simulate Payment

curl https://api.xendit.co/v2/payment_methods/pm-b264541b-286d-4044-bac0-ace45b158bef/payments/simulate -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 507000
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
Path Parameter Type Description
id
required
string Payment Method ID. This starts with the prefix pm-. You will get this ID from payment request's response in the payment_method object.
Body Parameter Type Description
amount
required
number The amount that needs to be paid. For a close amount case, the amount must be the expected amount stated in the payment request.

Response Parameters


Body Parameter Type Description
status
required
string The status of the request. If it successfully being processed then the status will be PENDING.
message
required
string Additional information regarding the payment simulation process

Example Simulate Payment Success Response

{
   "status": "PENDING",
   "message": "We're processing payment for payment method ID [pm-xxx] and will send you the result via callback. Please make sure you've set a callback URL in "Payment Succeeded" section in Callback settings in Xendit Dashboard. If you don't receive the callback within the next 5 minutes, please contact us."
}

Error Codes

Error Code Description
INCORRECT_AMOUNT
400
Incorrect amount. The expected amount for this payment method is xxxx.
INACTIVE_PAYMENT_METHOD
400
Could not pay callback {payment method} that is inactive
API_VALIDATION_ERROR
400
There is invalid input in one of the required request fields
PAYMENT_METHOD_NOT_SUPPORTED
400
Simulate Payment API supports VA, OTC, and QR Payment Method. Please try again using VA/OTC/QR Payment Method ID.
REQUEST_FORBIDDEN_ERROR
403
Simulate Payment API cannot be accessed using Live API Key. Please try again using Test API Key and Payment Method ID.
INVALID_API_KEY
401
API key format is invalid.
DATA_NOT_FOUND
404
Provided payment_method_id is invalid, not found or access is unauthorized.
SERVER_ERROR
500
An unexpected error occured. Our team has been notified and will troubleshoot the issue

Webhook QR Payment Succeeded

Callback Payload

Example: Payment Succeeded Callback Payload

{
  "created": "2023-05-31T07:38:58.373Z",
  "business_id": "5ddb77c8f4177f1ef8a44939",
  "event": "payment.succeeded",
  "api_version": null,
  "data": {
    "amount": 15000,
    "channel_properties": null,
    "country": "ID",
    "created": "2023-05-31T07:38:57.752591Z",
    "currency": "IDR",
    "customer_id": null,
    "description": null,
    "failure_code": null,
    "id": "qrpy_cb762db3-d37d-4097-8716-d2a26d23f61d",
    "items": null,
    "metadata": {
      "foo": "bar"
    },
    "payment_detail": {
      "issuer_name": "DANA",
      "receipt_id": ""
    },
    "payment_method": {
      "billing_information": {
        "city": null,
        "country": "",
        "postal_code": null,
        "province_state": null,
        "street_line1": null,
        "street_line2": null
      },
      "card": null,
      "created": "2023-05-31T07:22:47.050187Z",
      "description": null,
      "direct_bank_transfer": null,
      "direct_debit": null,
      "ewallet": null,
      "id": "pm-c10989bf-87d8-4ac4-a20d-94ea40624d93",
      "metadata": null,
      "over_the_counter": null,
      "qr_code": {
        "amount": null,
        "channel_code": "LINKAJA",
        "channel_properties": {
          "qr_string": "some-random-qr-string",
          "expires_at": "2023-10-25T00:00:00Z"
        },
        "currency": "IDR"
      },
      "reference_id": "4a148603-b094-4e81-a3e4-5e4e77b6feac",
      "reusability": "MULTIPLE_USE",
      "status": "ACTIVE",
      "type": "QR_CODE",
      "updated": "2023-05-31T07:22:47.050187Z",
      "virtual_account": null
    },
    "payment_request_id": "pr-4e96d8ab-4f5c-4a11-ab24-25e72ecd7901",
    "reference_id": "4a148603-b094-4e81-a3e4-5e4e77b6feac",
    "status": "SUCCEEDED",
    "updated": "2023-05-31T07:38:57.752591Z"
  }
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook QR Expired Callback

This callback is triggered when the Virtual Account, QR string, or Fixed payment have has been successfully activated and can be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Expired Callback Payload

{
    "id": "pm-34b2ed73-7486-4848-8112-57546175e336",
    "data": {
        "id": "pm-34b2ed73-7486-4848-8112-57546175e336",
        "card": null,
        "type": "QR_CODE",
        "status": "EXPIRED",
        "actions": [],
        "country": "ID",
        "created": "2023-08-09T09:40:32.659773Z",
        "ewallet": null,
        "qr_code": {
            "amount": 15000,
            "currency": "IDR",
            "channel_code": "DANA",
            "channel_properties": {
                "qr_string": "some-random-qr-string",
                "expires_at": "2023-08-11T09:40:32.650188Z"
            }
        },
        "updated": "2023-08-09T09:40:50.718860278Z",
        "metadata": null,
        "business_id": "628db55f8378fa6f14db977f",
        "customer_id": null,
        "description": null,
        "reusability": "ONE_TIME_USE",
        "direct_debit": null,
        "failure_code": null,
        "reference_id": "e39c3914-eee3-49be-aa01-f8a7d91d2c75",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "street_line1": null,
            "street_line2": null,
            "province_state": null
        },
        "direct_bank_transfer": null
    },
    "event": "payment_method.expired",
    "created": "2023-08-09T09:40:50.784698244Z",
    "business_id": "628db55f8378fa6f14db977f"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.expired
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status EXPIRED

Over The Counter

Fixed Payment Code Creation

This endpoint is provided to create fixed payment code, hence your end customer is able to generate code to pay via retailer.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 10000,
    "currency": "IDR",
    "country": "ID",
    "payment_method": {
        "type": "OVER_THE_COUNTER",
        "reusability": "ONE_TIME_USE",
        "over_the_counter": {
            "channel_code": "ALFAMART",
            "channel_properties": {
                "customer_name": "John Doe"
            }
        }
    },
    "metadata": {
        "foo": "bar"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
optional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is only available if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Note: Only one of payment_method{} or payment_method_id must be present.
Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.
The details of parameters is shown here:
Parameter Description
type
required
string Type of payment method
Accepted values:
  • OVER_THE_COUNTER
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For VIRTUAL_ACCOUNT, OVER_THE_COUNTER, and QR_CODE, this determines whether or not the payment instrument stays valid after a successful payment is made.

Accepted values:
  • ONE_TIME_USE - Payment method is expired after one successful payment.
  • MULTIPLE_USE - Payment method is tokenized and may be reused for subsequent payments.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.

For OVER_THE_COUNTER, QR_CODE, and VIRTUAL_ACCOUNT, this will be extended to the actual payments made.

Maximum length: 255 characters
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
over_the_counter
conditional
object Required for type='OVER_THE_COUNTER', this contains the necessary information to describe an over-the-counter payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported virtual account and their channel codes can be found in supported channels section
channel_properties
required
object Object that contains the information to generate a valid payment code

Key Value
customer_name
required
string Complete name of the payor. May be used by the channel partner to verify their identity. Must contain letters and space only.
payment_code
optional
string The payment code that you want to assign, e.g 12345. If none is provided, one will be generated at random.

Default: 8 random alphanumeric characters (e.g. ABCD1234)

Note: Do not include your prefix on this field.
expires_at
optional
ISO 8601 string The date and time in ISO 8601 UTC+0 when the payment code will be expired.

Default: The default validity period will be 31 years for Indonesian channels and 2 days for Philippine channels from creation date.

Note: The minimum is 2 hours and the maximum is 9 days for 7ELEVEN
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-ab565bdf-d506-4aaa-bd1d-e48a8bc83b70",
    "country": "ID",
    "amount": 10000,
    "currency": "IDR",
    "business_id": "628db55f8378fa6f14db977f",
    "reference_id": "90392f42-d98a-49ef-a7f3-f3c0f4008a04",
    "payment_method": {
        "id": "pm-b4eff3d2-1fe2-41d3-867e-62cc5028438a",
        "type": "OVER_THE_COUNTER",
        "reference_id": "62c21e3e-9bef-40b0-bf2f-a42c4eaae770",
        "description": null,
        "created": "2023-07-18T02:45:30.940372554Z",
        "updated": "2023-07-18T02:45:30.940372554Z",
        "card": null,
        "ewallet": null,
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": {
            "amount": 10000,
            "currency": "IDR",
            "channel_code": "ALFAMART",
            "channel_properties": {
                "payment_code": "APAPMFQ5ERCG4",
                "customer_name": "John Doe",
                "expires_at": "2023-07-20T02:45:30Z"
            }
        },
        "virtual_account": null,
        "qr_code": null,
        "metadata": {
            "foo": "bar"
        },
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "ONE_TIME_USE",
        "status": "ACTIVE"
    },
    "description": null,
    "metadata": {
        "foo": "bar"
    },
    "customer_id": null,
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-18T02:45:30.779418878Z",
    "updated": "2023-07-18T02:45:30.779418878Z",
    "status": "PENDING",
    "actions": [],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.


Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_API_KEY
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
OPERATION_NOT_ALLOWED
403
Operation being attempted is not supported for the provided payment method type or channel (eg. VA expiration date, VA suggested/expected amount, VA fixed amount) / Auth for the provided payment method ID is not supported .

Webhook Fixed Payment Code Activated

This callback is triggered when the Virtual Account, QR string, or Fixed payment have has been successfully activated and can be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{
    "id": "pm-ce27c3ba-e854-414e-aec6-cb7aa8d82c0b",
    "data": {
        "id": "pm-ce27c3ba-e854-414e-aec6-cb7aa8d82c0b",
        "card": null,
        "type": "OVER_THE_COUNTER",
        "status": "ACTIVE",
        "actions": [],
        "country": "PH",
        "created": "2023-06-20T06:26:52.590918576Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2023-06-20T06:26:52.590918576Z",
        "metadata": {
            "foo": "bar"
        },
        "business_id": "6396e6d48c59c18ca0e55218",
        "customer_id": null,
        "description": null,
        "reusability": "ONE_TIME_USE",
        "direct_debit": null,
        "failure_code": null,
        "reference_id": "2200765f-303e-4345-af20-28e2e0aeb3e4",
        "virtual_account": null,
        "over_the_counter": {
            "amount": 10000,
            "currency": "PHP",
            "channel_code": "CEBUANA",
            "channel_properties": {
                "expires_at": "2023-06-22T06:26:52Z",
                "payment_code": "PHLTRA87887623535",
                "customer_name": "John Doe"
            }
        },
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "street_line1": null,
            "street_line2": null,
            "province_state": null
        },
        "direct_bank_transfer": null
    },
    "event": "payment_method.activated",
    "created": "2023-06-20T06:26:52.772429487Z",
    "business_id": "6396e6d48c59c18ca0e55218"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

Simulate OTC Payment (Test Mode)

Simulate Payments API allows you to emulate your customer behavior to pay to your payment request (i.e. Virtual Account, Over-the-counter / Retail Outlet, QR Code) in TEST mode.

A callback will be sent to your callback URL upon payment completion. Please refer to the callback section for further information about the callback that will be delivered.

Endpoint: Perform Capture Payment

POST https://api.xendit.co/v2/payment_methods/{id}/payments/simulate

Request Parameters

Example Perform Simulate Payment

curl https://api.xendit.co/v2/payment_methods/pm-b264541b-286d-4044-bac0-ace45b158bef/payments/simulate -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 507000
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
Path Parameter Type Description
id
required
string Payment Method ID. This starts with the prefix pm-. You will get this ID from payment request's response in the payment_method object.
Body Parameter Type Description
amount
required
number The amount that needs to be paid. For a close amount case, the amount must be the expected amount stated in the payment request.

Response Parameters


Body Parameter Type Description
status
required
string The status of the request. If it successfully being processed then the status will be PENDING.
message
required
string Additional information regarding the payment simulation process

Example Simulate Payment Success Response

{
   "status": "PENDING",
   "message": "We're processing payment for payment method ID [pm-xxx] and will send you the result via callback. Please make sure you've set a callback URL in "Payment Succeeded" section in Callback settings in Xendit Dashboard. If you don't receive the callback within the next 5 minutes, please contact us."
}

Error Codes

Error Code Description
INCORRECT_AMOUNT
400
Incorrect amount. The expected amount for this payment method is xxxx.
INACTIVE_PAYMENT_METHOD
400
Could not pay callback {payment method} that is inactive
API_VALIDATION_ERROR
400
There is invalid input in one of the required request fields
PAYMENT_METHOD_NOT_SUPPORTED
400
Simulate Payment API supports VA, OTC, and QR Payment Method. Please try again using VA/OTC/QR Payment Method ID.
REQUEST_FORBIDDEN_ERROR
403
Simulate Payment API cannot be accessed using Live API Key. Please try again using Test API Key and Payment Method ID.
INVALID_API_KEY
401
API key format is invalid.
DATA_NOT_FOUND
404
Provided payment_method_id is invalid, not found or access is unauthorized.
SERVER_ERROR
500
An unexpected error occured. Our team has been notified and will troubleshoot the issue

Webhook OTC Payment Succeeded

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "created": "2023-06-21T10:22:09.537Z",
    "business_id": "628db55f8378fa6f14db977f",
    "event": "payment.succeeded",
    "data": {
        "id": "pymt-6bd92321-1dd3-4007-ba6d-ba9778f78bf9",
        "items": null,
        "amount": 10000,
        "status": "SUCCEEDED",
        "country": "ID",
        "created": "2023-06-21T10:22:06.894508924Z",
        "updated": "2023-06-21T10:22:06.894508924Z",
        "currency": "IDR",
        "metadata": {
            "foo": "bar"
        },
        "customer_id": null,
        "description": null,
        "failure_code": null,
        "reference_id": "16439b4d-3bf3-4261-8bde-9c8f51621ff2",
        "payment_detail": {
            "remarks": "payment simulation"
        },
        "payment_method": {
            "id": "pm-e4823b4d-02d8-4bac-b4d4-19a86e2201bb",
            "card": null,
            "type": "OVER_THE_COUNTER",
            "status": "EXPIRED",
            "created": "2023-06-21T10:21:45.42122Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2023-06-21T10:22:09.477374419Z",
            "metadata": {
                "foo": "bar"
            },
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": null,
            "reference_id": "16439b4d-3bf3-4261-8bde-9c8f51621ff2",
            "virtual_account": null,
            "over_the_counter": {
                "amount": 10000,
                "currency": "IDR",
                "channel_code": "ALFAMART",
                "channel_properties": {
                    "expires_at": "2023-06-23T10:21:45Z",
                    "payment_code": "APAPM8788765223",
                    "customer_name": "John Doe"
                }
            },
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-2d95854f-fc29-40b6-89cc-acb8085b3b1b"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Tokenized Payment Scenario

This payment method involves tokenization, where the process begins with the end user establishing an account link before proceeding to make subsequent payments.

Cards

Our Credit Cards API enables you to seamlessly charge Indonesian and international credit / debit cards from major schemes: Visa, MasterCard and JCB. To accept AMEX payments, you'll need your own merchant account with Bank Central Asia in Indonesia.

Tokenization

Tokenization is the process where card details (account number and expiration date) are securely collected on the client-side, so that sensitive card data is never passed through your systems. Tokens (in the form of payment_method_id) are then used to create Cards payment requests. It is important to pass us the details of the cardholder such as their contact details and billing/shipping details, as these will be used for 3DS authentication later on.

See our Tokenization Sample for an example implementation for web application. SDK implementations for mobile OS are in the works and are not available at the moment.

Multiple Use Tokens

Tokens can be created for multiple use. If you plan to save a card for future use, set reusability to MUTLPLE_USE (recommended). When tokenizing a card for multi-use, the amount field is optional.

Once you completed the tokenization step using XenditJS, you will receive a payment method activated webhook. Do save the specified payment_method_id (id prefixed with pm-) as it will be used in the payment request creation step.

Initiate Tokenized Payment

Using the payment_method_id saved from the tokenization step, you can now create a payment request to proceed with charging.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "reference_id": "merchant_internal_order_id",
    "currency": "IDR",
    "amount": 100000,
    "payment_method_id": "pm-4cf0be16-6339-4f27-a62d-e71dc570268d",
    "metadata": {
        "sku": "ABCDEFGH"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • MYR
  • VND
  • THB
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • VND - Only supports positive integers.
  • MYR - Supports up to two decimal places.
  • THB - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is required if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • VN - Vietnam
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method_id
required
string Unique identifier for the payment method. This has a prefix of pm-. When using XenditJS library on the client-side, this value will be generated by the createPaymentMethod function. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-a5b8c440-e32a-4556-baa6-0b3e7de362ea",
    "country": "ID",
    "amount": 15000,
    "currency": "IDR",
    "business_id": "666db55f3921fa6f14db977f",
    "reference_id": "facbb1a8-b6ee-49b6-8f74-72021bdcd22a",
    "payment_method": {
        "id": "pm-4cf0be16-6332-4f27-a62d-e71dc322668d",
        "type": "CARD",
        "reference_id": "a7f7807b-b3c9-41b4-afd1-53dc58c2af88",
        "description": "This is a description.",
        "created": "2023-01-19T08:57:02.101083Z",
        "updated": "2023-01-19T08:59:10.89757Z",
        "card": {
            "currency": "IDR",
            "channel_properties": {
                "skip_three_d_secure": false,
                "success_return_url": "https://xendit.co/goodstuff",
                "failure_return_url": "https://xendit.co/badstuff",
                "cardonfile_type": "CUSTOMER_UNSCHEDULED"
            },
            "card_information": {
                "token_id": "63c905dd8c4a98001b7c777a",
                "masked_card_number": "666000XXXXXX1666",
                "cardholder_name": "John Doe",
                "expiry_month": "12",
                "expiry_year": "2027",
                "fingerprint": "61f632879e9e27001a8165b9",
                "type": "CREDIT",
                "network": "VISA",
                "country": "ID",
                "issuer": "BRI"
            },
            "card_verification_results": {
                "address_verification_result": "MATCH",
                "cvv_result": "MATCH",
                "three_d_secure": {
                    "eci_code": "05",
                    "three_d_secure_flow": "CHALLENGE",
                    "three_d_secure_result": "AUTHENTICATED",
                    "three_d_secure_result_reason": null,
                    "three_d_secure_version": "2.1.0"
                }
            }
        },
        "ewallet": null,
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": {
            "foo": "bar"
        },
        "reusability": "MULTIPLE_USE",
        "status": "ACTIVE"
    },
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    },
    "customer_id": null,
    "capture_method": "AUTOMATIC",
    "initiator": "CUSTOMER",
    "card_verification_results": null,
    "created": "2023-01-19T16:43:05.960659909Z",
    "updated": "2023-01-19T16:43:05.960659909Z",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://redirect.xendit.co/callbacks/v2/authorizations/ca_63c9731a54c8da001a01491f/authentication_redirect?api_key=xnd_public_development_xsvgZdan9aqY1w5Szfn8XxzDOv3UDZkBRdDT6fZuVpKLVNrvQvS00TDuSLhp",
            "url_type": "WEB",
            "method": "GET",
            "qr_code": null
        }
    ],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.

Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • VND - Only supports positive integers.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
business_id
required
string Xendit-generated identifier for the business that owns the transaction
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.
customer_id
nullable
string ID of the customer object to which the account token will be linked to
capture_method
nullable
string Describes when the funds are captured.
Defaults to AUTOMATIC
Possible values:
  • AUTOMATIC - Xendit triggers capture upon successful authorization
  • MANUAL - Merchant has to trigger capture after successful authorization. Only supported for payment method type CARD
initiator
required
string Identifies whether the payment is initiated by the end-customer or the merchant.
Defaults to CUSTOMER
Possible values:
  • CUSTOMER - The transaction was initiated by the payor
  • MERCHANT - The transaction was initiated by the merchant
card_verification_results
nullable
object This is only applicable for CARD transactions. This contains the results of various checks done to verify the transaction such as CVV, and AVS.
Key Value
three_d_secure
nullable
object Only applicable for Payment Requests when 3DS is performed
Indicates the result of any 3DS transaction initiated when Payment Request creation is performed using 3DS.
Note that each 3DS transaction performed using a unique Payment Method will be unique and may have a different three_ds_result unique for each Payment Request.

Key Value
three_d_secure_flow
required
string Whether the 3DS transaction went through a frictionless or challenge flow.
Possible values:
  • FRICTIONLESS - 2FA was not required
  • CHALLENGE - 2FA was required via OTP or other means
eci_code
required
string Electronic Commerce Indicator (ECI) is a number that indicates the level of security that was used when obtaining the customerโ€™s payment credentials.
An ECI is included as part of the authorization request for each transaction.
Possible values:
  • 00 - Unable to authenticate (Mastercard)
  • 01 - Authentication attempted (Mastercard)
  • 02 - Successful authentication (Mastercard)
  • 05 - Successful authentication (Visa, AMEX, JCB)
  • 06 - Authentication attempted (Visa, AMEX, JCB)
  • 07 - Unable to authenticate (Visa, AMEX, JCB)
three_d_secure_result
required
string The result of the 3DS authentication.
Possible values:
  • SUCCESSFUL [ECI 02 / 05] - 3DS authentication was successful. Liability shift available.
  • ATTEMPTED [ECI 01 / 06] - 3DS authentication was attempted, but not completed. This could be due to either: issuer does not support 3DS, issuer supports 3DS but card not enabled for 3DS, or issuer 3DS server experiencing an outage. In most cases, liability shift is available
  • FAILED [ECI 00 / 07] - 3DS authentication failed. Liability shift not available. authorization request must not be submitted.
  • NOT_AVAILABLE [No ECI code being returned] - 3DS could not be performed on this card. In most cases, you can proceed to authorization request but liability shift will not be available.
  • PROCESSING_ERROR [No ECI code being returned] - An issue occurred with the issuerโ€™s 3DS server or with the card processor, and no proof of any 3DS attempt can be provided. In most cases, liability shift will not be available.
three_d_secure_version
nullable
string Indicates the 3DS version.

Possible values:
  • null - if no 3DS version returned by the processor
  • 1.0.x - 3DS version 1.0, the basic version. From 2021 onwards, high chance that there will be no chargeback liability shift for payments using 3DS 1.0.
  • 2.1.x - Minimum version returned for EMV 3DS. Frictionless authentication is possible.
  • 2.2.x - Upgraded version returned for EMV 3DS. Returned if more advanced authentication methods are used, such as biometrics.
cvv_result
nullable
Indicates the result from verifying the Card Validation Value / Card Validation Code (CVV / CVC) when creating the Payment Method / token.
Possible values:
  • MATCHED - CVV entered matched issuerโ€™s records.
  • NOT_MATCHED - CVV entered did not match issuerโ€™s records. Try entering the CVV again or a different card.
  • NOT_PROCESSED - CVV entered was not processed, for an unspecified reason. Try repeating the transaction and re-entering the CVV.
  • NOT_INCLUDED - CVV exists on the card but was not included in the request
  • VALIDATION_FAILED - CVV entered failed data validation. Try repeating the transaction and re-entering the CVV.
  • SUSPICIOUS_TRANSACTION - The transaction was considered suspicious by the issuer. Try a different card.
  • NOT_SUPPORTED - CVV verification is not supported by the issuer, card association, or processor.
  • UNKNOWN_FROM_PROCESSOR - Unrecognized or no result code returned by processor.
address_verification_result
nullable
Only applicable for cards issued in USA, CAN or the UK.
Indicates the result from verifying the street address and zip code provided when creating the Payment Request.
Possible values:
  • MATCHED - Street address and zip code match.
  • NOT_MATCHED - Street address and zip code entered do not match issuerโ€™s records. Try repeating the transaction and re-entering the address and zip.
  • NOT_MATCHED_NAME - Street address and zip code entered match issuerโ€™s records, but not cardholder name. Try repeating the transaction and re-entering the cardholder name.
  • PARTIAL_MATCH_ADDRESS - Street address entered matches issuerโ€™s records, but not the zip code. Try repeating the transaction and re-entering the zip and/or cardholder name.
  • PARTIAL_MATCH_ZIP - Zip code entered matches issuerโ€™s records, but not the street address. Try repeating the transaction and re-entering the address and/or cardholder name.
  • PARTIAL_MATCH_NAME - Cardholder name entered matches issuerโ€™s records, but not the street address and zip code. Try repeating the transaction and re-entering the street address and zip.
  • INVALID - Address verification data provided was invalid, or it is not allowed for this card type.
  • NOT_SUPPORTED - Address verification is not supported for this card
  • NOT_AVAILABLE - The address verification system is temporarily unavailable. Try repeating the transaction again later.
  • UNKNOWN_FROM_PROCESSOR - The processor returned an unrecognized value for the address verification response.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to complete the payment. Typical actions are for merchant to trigger OTP validation or redirect your customer to an authentication page.
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
  • SUCCEEDED - The payment was successfully completed.
  • FAILED - The payment request failed. See failure_code for the specific reason why the transaction failed.
  • AWAITING_CAPTURE - The payment request is eligible for manual capture and is awaiting the trigger of the manual Capture API.
actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to complete a payment. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
See possible codes here.
channel_properties
nullable
object Specific settings applied to the payment request, overwriting the ones in the Payment Method object.
For CARD:
Key Value
skip_three_d_secure
required
boolean To indicate whether to perform 3DS on the payment request
Defaults to false
success_return_url
nullable
string URL where the end-customer is redirected if the linking is successful.
Required when skip_three_d_secure = false.
This will be null if not applicable.
failure_return_url
nullable
string URL where the end-customer is redirected if the linking has failed.
Required when skip_three_d_secure = false.
This will be null if not applicable.

shipping_information
nullable
object Object containing the payor's shipping address.
Key Value
country
required
string 2-letter ISO 3166-2 country code for the customerโ€™s shipping country
street_line1
nullable
string Building name and apartment unit number
street_line2
nullable
string Building street address
city
nullable
string City, village or town as appropriate
province_state
nullable
string Either one of (whichever is applicable):
  • Geographic area, province, or region
  • Formal state designation within country
postal_code
nullable
string Postal, zip or rural delivery code, if applicable
items
nullable
array Array of objects describing the item/s purchased

Object parameters
Key Value
type
required
string Type of item

DIGITAL_PRODUCT, PHYSICAL_PRODUCT, DIGITAL_SERVICE, PHYSICAL_SERVICE,FEE,DISCOUNT (Atome does not support DISCOUNT)
reference_id
required
string Merchantโ€™s identifier for specific item (ie. SKU, promotion code, etc)

Format Special and alphanumeric
Max length 255 characters
name
required
string Item name

Format Special and alphanumeric
Max length 255 characters
net_unit_amount
required
number Net amount to be charged per unit, please put negative amount for DISCOUNT (e.g. -1000000)
quantity
required
number Number of units of this item in the basket

Min 1
url
required
string URL of the item

Must be HTTPS or HTTP
category
required
string Merchant category for item

Format Special and alphanumeric
Max length 255 characters
subcategory
optional
string Merchant subcategory for item

Format Special and alphanumeric
Max length 255 characters
description
optional
string Item description

Format Special and alphanumeric
Max length 255 characters
metadata
optional
object Additional object that may be used for additional item attributes

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
PROCESSOR_CONFIGURATION_ERROR
500
Payment declined due to a problem with the merchant configuration on the Card Processor. Contact Xendit to troubleshoot the issue.
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
INSUFFICIENT_BALANCE
400
Source of funds has insufficient balance to complete the transaction
MAX_AMOUNT_LIMIT_ERROR
400
The transaction amount exceeds the partner channel's set limits
INVALID_PAYMENT_METHOD
400
The provided payment method id has already expired or is inactive
ACCOUNT_NOT_ACTIVATED
400
End-customer's account is not activated for payments.
CUSTOMER_UNREACHABLE
400
The end-user's device cannot be reached at this moment

Webhook Payment Succeeded Cards

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "created": "2023-05-31T08:18:13.473Z",
    "business_id": "628db55f8378fa6f14db977f",
    "event": "payment.succeeded",
    "data": {
        "id": "ca_f545a7d9-482b-4eb0-b175-032252d3acca",
        "items": null,
        "amount": 1500,
        "status": "SUCCEEDED",
        "country": "ID",
        "created": "2023-05-31T08:17:40.193463Z",
        "updated": "2023-05-31T08:18:13.042335Z",
        "currency": "IDR",
        "metadata": null,
        "customer_id": null,
        "description": null,
        "failure_code": null,
        "reference_id": "8346c97c-6c16-4745-a1b4-69656f0b2d4e",
        "payment_detail": null,
        "payment_method": {
            "id": "pm-62e521fc-09bd-4d50-bc44-a190c482a1a5",
            "type": "CARD",
            "status": "EXPIRED",
            "created": "2023-05-31T08:17:40.084679Z",
            "card": {
                "currency": "IDR",
                "channel_properties": {
                    "skip_three_d_secure": false,
                    "success_return_url": "https://xendit.co/goodstuff",
                    "failure_return_url": "https://xendit.co/badstuff",
                    "cardonfile_type": "CUSTOMER_UNSCHEDULED"
                },
                "card_information": {
                    "token_id": "63c905dd8c4a98001b7c777a",
                    "masked_card_number": "666000XXXXXX1666",
                    "cardholder_name": "John Doe",
                    "expiry_month": "12",
                    "expiry_year": "2027",
                    "fingerprint": "61f632879e9e27001a8165b9",
                    "type": "CREDIT",
                    "network": "VISA",
                    "country": "ID",
                    "issuer": "BRI",
                    "cardholder_email": "johndoe@gmail.com",
                    "cardholder_phone_number": "628212223242526"
                },
                "card_verification_results": {
                    "address_verification_result": "MATCH",
                    "cvv_result": "MATCH",
                    "three_d_secure": {
                        "eci_code": "05",
                        "three_d_secure_flow": "CHALLENGE",
                        "three_d_secure_result": "AUTHENTICATED",
                        "three_d_secure_result_reason": null,
                        "three_d_secure_version": "2.1.0"
                    }
                }
            },
            "ewallet": null,
            "qr_code": null,
            "updated": "2023-05-31T08:17:40.084679Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": null,
            "reference_id": "6c8ad38e-2925-44c4-95af-35003298eefa",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-dd5e558f-1001-4402-84c3-df4375c6b29f"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook Payment Failed Cards

Note: Make sure that you ONLY have a webhook URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate webhooks, DO NOT fill out product-specific sections.

Webhook Payload

Example: Payment Failed Webhook Payload

{
    "created": "2023-05-31T10:52:00.666Z",
    "business_id": "628db55f8378fa6f14db9555",
    "event": "payment.failed",
    "data": {
        "id": "ewc_df746164-4f3e-417e-84cd-fa78c1d6a555",
        "items": null,
        "amount": 20111,
        "status": "FAILED",
        "country": "ID",
        "created": "2023-05-31T10:51:48.73712Z",
        "updated": "2023-05-31T10:51:58.057377Z",
        "currency": "IDR",
        "metadata": null,
        "customer_id": null,
        "description": null,
        "failure_code": "ACCOUNT_NOT_ACTIVATED",
        "reference_id": "7ce8f500-1bad-4d46-a1eb-0879b13e1bba",
        "payment_detail": null,
        "payment_method": {
            "id": "pm-8bfd2cf3-6aca-4a10-ba48-d5c9e303b5df",
            "card": {
                "currency": "IDR",
                "channel_properties": {
                    "skip_three_d_secure": false,
                    "success_return_url": "https://xendit.co/goodstuff",
                    "failure_return_url": "https://xendit.co/badstuff",
                    "cardonfile_type": "CUSTOMER_UNSCHEDULED"
                },
                "card_information": {
                    "token_id": "63c905dd8c4a98001b7c777a",
                    "masked_card_number": "666000XXXXXX1666",
                    "cardholder_name": "John Doe",
                    "expiry_month": "12",
                    "expiry_year": "2027",
                    "fingerprint": "61f632879e9e27001a8165b9",
                    "type": "CREDIT",
                    "network": "VISA",
                    "country": "ID",
                    "issuer": "BRI"
                },
                "card_verification_results": {
                    "address_verification_result": "MATCH",
                    "cvv_result": "MATCH",
                    "three_d_secure": {
                        "eci_code": "05",
                        "three_d_secure_flow": "CHALLENGE",
                        "three_d_secure_result": "AUTHENTICATED",
                        "three_d_secure_result_reason": null,
                        "three_d_secure_version": "2.1.0"
                    }
                }
            },
            "type": "EWALLET",
            "status": "EXPIRED",
            "created": "2023-05-31T10:51:48.646147Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2023-05-31T10:51:48.646147Z",
            "metadata": null,
            "description": null,
            "reusability": "ONE_TIME_USE",
            "direct_debit": null,
            "reference_id": "869776db-5e5a-48dd-b7b3-45b89737e599",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-63df12be-6dc2-4602-ab7a-78d851f0ee06"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.
INVALID_ACCOUNT_DETAILS
The provided details were rejected by the partner channel due to incorrect information.
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel

Direct Debit

Account Linking (Direct Debit)

Account linking in direct debit enable you to abstract sources of funds, account authorizations and use them for making direct debit payments or recurring payments.

Endpoint: Create Payment Method

POST https://api.xendit.co/v2/payment_methods

Example Create Payment Method Request

curl https://api.xendit.co/v2/payment_methods -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "type": "DIRECT_DEBIT",
    "direct_debit": {
        "channel_code": "BPI",
        "channel_properties": {
            "success_return_url" : "https://redirect.me/goodstuff",
            "failure_return_url" : "https://redirect.me/badstuff"
        }
    },
    "reusability": "MULTIPLE_USE",
    "customer_id": "cust-xxx"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information


Request Body Parameter Type Description
type
required
string Type of payment method
For Direct debit:
  • DIRECT_DEBIT
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For DIRECT_DEBIT, this determines whether or not authentication is performed again for subsequent payments.

Accepted values for account linking:

use MULTIPLE_USE as value for direct debit account linking.
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.


customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID. The value will always have prefix cust-xxx

A customer_id is required for all DIRECT_DEBIT payment methods and if customer object is null.
customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is required only if customer_id is null
The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL
individual_detail
conditional
object JSON object containing details of the individual.
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction.

Accepted values for Direct debit:
  • ID - Indonesia
  • PH - Philippines
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
direct_debit
conditional
object Required for type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported banks and their channel codes:
  • Indonesia
    • BRI
    • MANDIRI
  • Philippines
    • BPI
    • BPI_RECURRING
    • UBP
    • UBP_EADA
    • RCBC
    • CHINABANK

  • Thailand
    • SCB
    • KTB
    • BBL
    • BAY

  • Malaysia
channel_properties
required
object Object that contains the required information to perform payments using direct debit

BRI Direct Debit required fields
Key Value
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
card_last_four
required
string Last four digits of the debit card
card_expiry
optional
string Expiry month and year of the debit card (in MM/YY format)
email
required
string Email address of the customer that is registered to the partner channel

MANDIRI, BPI, UBP, RCBC, CHINABANK, and FPX Channels under Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
SCB and BBL Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
KTB and BAY Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.

Create Direct Debit Account Linking via Payment Method Response

Example Create Payment Method Success Response

{
    "id": "pm-04340cfc-9a9d-437b-9046-80133cd2b265",
    "type": "DIRECT_DEBIT",
    "country": "PH",
    "business_id": "6396e6d48c59c43843989",
    "customer_id": "cust-675b65af-a3d6-4945-aafe-3899389",
    "reference_id": "c3b17af5-16de-43bd-8165-22aa0c5c1bac",
    "reusability": "MULTIPLE_USE",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://link-web-staging.xendit.co/oauth/lat-ae030303-5155-4962-ba09-ac3b3aa1cef4/confirm",
            "url_type": "WEB",
            "method": "GET"
        }
    ],
    "description": null,
    "created": "2023-06-13T16:49:26.044862578Z",
    "updated": "2023-06-13T16:49:26.044862578Z",
    "metadata": null,
    "billing_information": null,
    "failure_code": null,
    "ewallet": null,
    "direct_bank_transfer": null,
    "direct_debit": {
        "channel_code": "BPI",
        "channel_properties": {
            "failure_return_url": "https://redirect.me/badstuff",
            "success_return_url": "https://redirect.me/goodstuff"
        },
        "type": "BANK_ACCOUNT",
        "bank_account": {
            "masked_bank_account_number": null,
            "bank_account_hash": null
        },
        "debit_card": null
    },
    "card": null,
    "over_the_counter": null,
    "qr_code": null,
    "virtual_account": null
}

A successful Payment Method creation returns a Payment Method Object with an HTTP 201 status code.



Body Parameter Type Description
id
required
string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

Possible value:
  • MULTIPLE_USE
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets.
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
  • ACTIVE - The payment method can be used for payment requests (for Cards, E-wallets, Direct Debit) or can now accept payments (for Virtual Account, Over-the-Counter, QR Code)
  • PENDING - The request is successfully passed, and need to acivate asynchronously. Please listen to our callback to get the updated status.

actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
type
required
string Type of payment method. Refer to the corresponding object to access further information

Possible values:
  • DIRECT_DEBIT
direct_debit
nullable
object For type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method. This will be null otherwise.
Please refer to Direct debit Object for more parameter details.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
created
required
string ISO 8601 Timestamp for Payment Method object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Method object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Method creation.

Create Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
INVALID_API_KEY
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details. If you provide customer object request, the reference_id of customer object may already exist.
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer


Authorize Payment Method Direct Debit Tokenized

This endpoint only applies to BRI Direct Debit. This is used when an additional authorization (ex. OTP Validation) is required in order to successfully activate a payment method. This is equivalent to the POST - AUTH action provided when a Payment Method has the status REQUIRES_ACTION.

Endpoint: Account Linking - Authorize Payment Method

POST https://api.xendit.co/v2/payment_methods/:id/auth

Authorize Payment Method Request

Example Account Linking - Authorize Payment Method Request

curl https://api.xendit.co/v2/payment_methods/pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a/auth -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "auth_code": "356443"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.
Request Body Parameter Type Description
auth_code
required
string The authorization code or OTP inputted by the end-customer.

Authorize Payment Method Response

Example Account Linking - Authorize Payment Method Success Response

{
  "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
  "card": null,
  "type": "DIRECT_DEBIT",
  "status": "ACTIVE",
  "actions": [],
  "country": "ID",
  "created": "2022-08-12T13:30:26.579048Z",
  "ewallet": null,
  "qr_code": null,
  "updated": "2022-08-12T13:30:58.908220358Z",
  "metadata": null,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "description": null,
  "reusability": "MULTIPLE_USE",
  "direct_debit": {
      "type": "DEBIT_CARD",
      "debit_card": {
        "mobile_number": "+62818555988",
            "card_last_four": "8888",
            "card_expiry": "06/24",
            "email": "email@email.com"
      },
      "bank_account": null,
      "channel_code": "BRI",
      "channel_properties": {
          "mobile_number": "+62818555988",
          "card_last_four": "8888",
          "card_expiry": "06/24",
          "email": "test.email@xendit.co"
      }
  },
  "failure_code": null,
  "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
  "virtual_account": null,
  "over_the_counter": null,
  "billing_information": null,
  "direct_bank_transfer": null,
  "business_id": "5f27a14a9bf05c73dd040bc8"
}

Returns a Payment Method Object with an HTTP 200 status code.

Authorize Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
EXPIRED_OTP_ERROR
400
The provided auth_code has expired
INVALID_OTP_ERROR
400
The provided auth_code is incorrect
MAX_OTP_ATTEMPTS_ERROR
400
The maximum attempts allowed by the channel has been reached
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
DATA_NOT_FOUND
404
The provided id did not match any of our records
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
PAYMENT_METHOD_ALREADY_ACTIVE
409
Cannot proceed because the payment method is already active or has been activated
PAYMENT_METHOD_ALREADY_FAILED
409
Cannot proceed because the payment method has failed authorization and cannot be retried
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

Webhook Account Linking Activated - Direct Debit

This callback activates when the end customer intends to connect their direct debit cards to your website for future payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{

    "event": "payment_method.activated",
    "data": {
        "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "ACTIVE",
        "actions": [],
        "country": "PH",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:58.908220358Z",
        "metadata": null,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                "masked_bank_account_number": "XXXXXX1234"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            }
        },
        "failure_code": null,
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "created": "2022-08-12T13:30:59.074277334Z",
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

Webhook Account Linking Failed - Direct Debit

This callback is triggered when a particular Payment Method has failed during authentication/authorization.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Failed Callback Payload

{
    "id": "pm-343c8d96-0b69-4f02-85ae-110336241f7e",
    "data": {
        "id": "pm-343c8d96-0b69-4f02-85ae-110336241f7e",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "FAILED",
        "actions": [],
        "country": "PH",
        "created": "2023-08-10T09:05:13.606327Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2023-08-10T09:05:21.301664958Z",
        "metadata": null,
        "business_id": "6396e6d48c59c18ca0e55218",
        "customer_id": "cust-19bfb7fd-6c8d-4332-8725-c14006090ea4",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": null,
                "masked_bank_account_number": null
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://redirect.me/badstuff",
                "success_return_url": "https://redirect.me/goodstuff"
            }
        },
        "failure_code": "PAYMENT_METHOD_ALREADY_EXISTS",
        "reference_id": "195f7edd-7394-44f4-8395-01b983c2c80a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "event": "payment_method.failed",
    "created": "2023-08-10T09:05:21.454587678Z",
    "business_id": "6396e6d48c59c18ca0e55218"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status FAILED. See the Failure Code table below to see the possible values of failure_code.

Payment Method Failure

This failure code will be delivered assynchronously with payment_methods.failed callback. Find details more in Payment Method Failed Callback

Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.

Subsequent Payment (Direct Debit)

This scenario facilitates the subsequent payment functionality following the account linking process. Please kindly find the details of account linking steps here.

After making the following payment, the next task is to verify it using an OTP (One-Time Password). There are two options for OTP validation:

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 1500,
    "currency": "PHP",
    "payment_method_id": "pm-e677f3d7-15f5-4991-8c8c-1fba70c72684",
    "description": "This is a description.",
    "channel_properties": {
        "success_return_url": "https://redirect.me/goodstuff?custom=value",
        "failure_return_url": "https://redirect.me/badstuff?custom=value"
    },
    "metadata": {
        "foo": "bar"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.

Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • THB
  • MYR
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method_id
conditional
object Note: Only one of payment_method{} or payment_method_id must be present.
ID of the ACTIVE Payment Method to be used in the payment.
channel_properties
optional
object Specific settings to be applied to the transaction. This also overwrites any common parameters with the Payment Method Object.
For BRI Direct Debit:
Key Value
require_auth
nullable
string Toggle used to require end-customer to input undergo OTP validation before completing a payment.
  • true
  • false
Default value: true

For BPI, UBP, RCBC, CHINABANK, and FPX Channels under Direct Debit:
Key Value
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
nullable
string URL where the end-customer is redirected if the authorization failed


For SCB and BBL Direct Debit:
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.


For KTB and BAY Direct Debit:
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.


metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490",
    "country": "PH",
    "amount": 1500,
    "currency": "PHP",
    "business_id": "6396e6d48c59c18ca0e55218",
    "reference_id": "464608e0-3fff-4ecc-83e9-ce57d2561b1c",
    "payment_method": {
        "id": "pm-e677f3d7-15f5-4991-8c8c-1fba70c72684",
        "type": "DIRECT_DEBIT",
        "reference_id": "80af8018-ec1b-48db-9ca2-a2bffc3fedf7",
        "description": null,
        "created": "2023-07-16T23:03:01.886251Z",
        "updated": "2023-07-16T23:03:13.898886Z",
        "card": null,
        "ewallet": null,
        "direct_debit": {
            "channel_code": "BPI",
            "channel_properties": {
                "success_return_url": "https://redirect.me/goodstuff",
                "failure_return_url": "https://redirect.me/badstuff"
            },
            "type": "BANK_ACCOUNT",
            "bank_account": {
                "masked_bank_account_number": "XXX1631",
                "bank_account_hash": "8f06b7dc684aa57a283adf49b2f67bdb11750ac04300f3996d97c7412ac5ca48"
            },
            "debit_card": null
        },
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "MULTIPLE_USE",
        "status": "ACTIVE"
    },
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    },
    "customer_id": "cust-d6bd4440-24b9-4199-bc09-b01c4eda049e",
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-16T23:03:44.877239112Z",
    "updated": "2023-07-16T23:03:44.877239112Z",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://direct-debit-web-dev.xendit.co/direct_debits/ddpy-4a33b665-80ca-4a93-a111-f52ba86ec7e3/checkout?failure_redirect_url=https%3A%2F%2Fredirect.me%2Fbadstuff%3Fcustom%3Dvalue&payment_redirect_delay=10",
            "url_type": "WEB",
            "method": "GET",
            "qr_code": null
        },
        {
            "action": "AUTH",
            "url": "https://api.xendit.co/payment_requests/pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490/auth",
            "url_type": "API",
            "method": "POST",
            "qr_code": null
        }
    ],
    "failure_code": null,
    "channel_properties": {
        "failure_return_url": "https://redirect.me/badstuff?custom=value",
        "success_return_url": "https://redirect.me/goodstuff?custom=value"
    },
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
PROCESSOR_CONFIGURATION_ERROR
500
Payment declined due to a problem with the merchant configuration on the Card Processor. Contact Xendit to troubleshoot the issue.
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
PROCESSOR_TEMPORARILY_UNAVAILABLE
503
The Card Processor appears to be temporarily unavailable. Wait for a couple minutes, then resend the request. If it fails again, Cardholder can try using a different card or other form of payment.
PROCESSOR_TIMEOUT_ERROR
503
Request was received by the processor, but there was a server timeout. Wait for a couple minutes and then retry the request.
INSUFFICIENT_BALANCE
400
Source of funds has insufficient balance to complete the transaction.
MAX_AMOUNT_LIMIT_ERROR
400
The transaction amount exceeds the partner channel's set limits.
FORBIDDEN
403
Provided API key does not have the correct permissions to perform the operation.

Authorize Payment Request Direct Debit Tokenized

This is only applicable for select payment DIRECT_DEBIT channels (BRI Direct Debit, BPI, RCBC, UBP, CHINABANK)

This is used when an additional authorization (ex. OTP Validation, PIN validation) is required in order to successfully activate a payment method. This is equivalent to the POST - AUTH action provided when a Payment Method has the status REQUIRES_ACTION.

Endpoint: Confirm Payment Request

POST https://api.xendit.co/payment_requests/:id/auth

Confirm Payment Request Request

Example Confirm Payment Request Request

curl https://api.xendit.co/payment_requests/pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f/auth -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "auth_code": "123456"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Request object. This starts with the prefix pr-.
Request Body Parameter Type Description
auth_code
required
string The authorization code, OTP, or PIN inputted by the end-customer.

Confirm Payment Request Response

Example Confirm Payment Request Response

{
  "id": "pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f",
  "currency": "PHP",
  "amount": 10000,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "status": "PENDING",
  "reference_id": "a2c66ceb-2cbe-4541-bb69-9f50fd2040e0",
  "payment_method": {
    "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
    "card": null,
    "type": "DIRECT_DEBIT",
    "status": "ACTIVE",
    "actions": [],
    "country": "PH",
    "ewallet": null,
    "qr_code": null,
    "metadata": null,
    "description": null,
    "reusability": "MULTIPLE_USE",
    "direct_debit": {
        "type": "BANK_ACCOUNT",
        "debit_card": null,
        "bank_account": {
            "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
            "masked_bank_account_number": "XXXXXX1234"
        },
        "channel_code": "BPI",
        "channel_properties": {
            "failure_return_url": "https://your-redirect-website.com/failure",
            "success_return_url": "https://your-redirect-website.com/success"
        }
    },
    "failure_code": null,
    "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
    "virtual_account": null,
    "over_the_counter": null,
    "billing_information": null,
    "direct_bank_transfer": null,
    "created": "2022-08-12T13:30:26.579048Z",
    "updated": "2022-08-12T13:30:58.908220358Z"
  },
  "channel_properties": null,
  "actions": [],
  "created": "2020-08-29T09:12:33.001Z",
  "updated": "2020-08-29T09:12:33.001Z",
  "metadata": {
    "sku": "ABCDEFGH"
  }
}

Returns a Payment Request Object with an HTTP 200 status code.

Confirm Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
EXPIRED_OTP_ERROR
400
The provided auth_code has expired
INVALID_OTP_ERROR
400
The provided auth_code is incorrect
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_OTP_ATTEMPTS_ERROR
400
The maximum attempts allowed by the channel has been reached
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
PAYMENT_REQUEST_ALREADY_FAILED
409
Cannot proceed because the payment method has already failed and cannot be retried.
PAYMENT_REQUEST_ALREADY_PENDING
409
Payment request ID already is processing and waiting for results from the partner channel.
PAYMENT_REQUEST_ALREADY_SUCCEEDED
409
Cannot proceed because the payment request has been successfully processed.
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

Resend Auth for Payment Request Tokenized (Direct Debit )

This is only applicable for select payment DIRECT_DEBIT channels (BPI, UBP, CHINABANK)

This is used when an additional authorization (ex. OTP Validation) is required in order to successfully activate a payment method. This is equivalent to the POST - AUTH action provided when a Payment Method has the status REQUIRES_ACTION.

Endpoint: Resend Auth for Payment Request

POST https://api.xendit.co/payment_requests/:id/auth/resend

Resend Auth for Payment Request Request

Example Resend Auth for Payment Request Request

curl https://api.xendit.co/payment_requests/pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f/auth/resend -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Request object. This starts with the prefix pr-.

Resend Auth for Payment Request Response

Example Resend Auth for Payment Request Success Response

{
  "id": "pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f",
  "currency": "PHP",
  "amount": 10000,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "status": "REQUIRES_ACTION",
  "reference_id": "a2c66ceb-2cbe-4541-bb69-9f50fd2040e0",
  "payment_method": {
    "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
    "card": null,
    "type": "DIRECT_DEBIT",
    "status": "ACTIVE",
    "actions": [],
    "country": "PH",
    "ewallet": null,
    "qr_code": null,
    "metadata": null,
    "description": null,
    "reusability": "MULTIPLE_USE",
    "direct_debit": {
        "type": "BANK_ACCOUNT",
        "debit_card": null,
        "bank_account": {
            "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
            "masked_bank_account_number": "XXXXXX1234"
        },
        "channel_code": "BPI",
        "channel_properties": {
            "failure_return_url": "https://your-redirect-website.com/failure",
            "success_return_url": "https://your-redirect-website.com/success"
        }
    },
    "failure_code": null,
    "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
    "virtual_account": null,
    "over_the_counter": null,
    "billing_information": null,
    "direct_bank_transfer": null,
    "created": "2022-08-12T13:30:26.579048Z",
    "updated": "2022-08-12T13:30:58.908220358Z"
  },
  "channel_properties": null,
  "actions": [
    {
      "action": "AUTH",
      "url_type": "API",
      "url": "https://api.xendit.co/payment_requests/pr-6e9778ea-7d62-40fe-8b25-a4d740754c5f/auth",
      "method": "POST"
    }
  ],
  "created": "2020-08-29T09:12:33.001Z",
  "updated": "2020-08-29T09:12:33.001Z",
  "metadata": {
    "sku": "ABCDEFGH"
  }
}

Returns a Payment Request Object with an HTTP 200 status code.

Resend Auth for Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DATA_NOT_FOUND
404
The provided id did not match any of our records
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
PAYMENT_REQUEST_ALREADY_FAILED
409
Cannot proceed because the payment method has already failed and cannot be retried.
PAYMENT_REQUEST_ALREADY_PENDING
409
Payment request ID already is processing and waiting for results from the partner channel.
PAYMENT_REQUEST_ALREADY_SUCCEEDED
409
Cannot proceed because the payment request has been successfully processed.
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

Webhook Payment Succeeded Direct Debit Tokenized

This is also send for successful Payment Requests for EWALLET, DIRECT_DEBIT, and CARD.

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "event": "payment.succeeded",
    "data": {
        "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
        "amount": 1000,
        "status": "SUCCEEDED",
        "country": "PH",
        "created": "2022-08-12T13:30:40.9209Z",
        "updated": "2022-08-12T13:30:58.729373Z",
        "currency": "PHP",
        "metadata": {
            "sku": "ABCDEFGH"
        },
        "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
        "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
        "payment_method": {
            "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
            "card": null,
            "type": "DIRECT_DEBIT",
            "status": "ACTIVE",
            "created": "2022-08-12T13:30:26.579048Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2022-08-12T13:30:40.221525Z",
            "metadata": null,
            "description": null,
            "reusability": "MULTIPLE_USE",
            "direct_debit": {
                "type": "BANK_ACCOUNT",
                "debit_card": null,
                "bank_account": {
                    "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                    "masked_bank_account_number": "XXXXXX1234"
                },
                "channel_code": "BPI",
                "channel_properties": {
                    "failure_return_url": "https://your-redirect-website.com/failure",
                    "success_return_url": "https://your-redirect-website.com/success"
                }
            },
            "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
            "virtual_account": null,
            "over_the_counter": null,
            "direct_bank_transfer": null
        },
        "description": null,
        "failure_code": null,
        "payment_detail": null,
        "channel_properties": null,
        "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
    },
    "created": "2022-08-12T13:30:58.986Z",
    "business_id": "5f27a14a9bf05c73dd040bc8",
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook Payment Failed Direct Debit Tokenized

This callback is sent when a pending EWALLET, DIRECT_DEBIT, and CARD has failed.

Note: Make sure that you ONLY have a callback URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate callbacks, DO NOT fill out product-specific sections.

Callback Payload

Example: Payment Failed Callback Payload

{
  "event": "payment.failed",
  "data": {
      "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
      "amount": 1000,
      "status": "FAILED",
      "country": "PH",
      "created": "2022-08-12T13:30:40.9209Z",
      "updated": "2022-08-12T13:30:58.729373Z",
      "currency": "PHP",
      "metadata": {
          "sku": "ABCDEFGH"
      },
      "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
      "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
      "payment_method": {
          "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
          "card": null,
          "type": "DIRECT_DEBIT",
          "status": "ACTIVE",
          "created": "2022-08-12T13:30:26.579048Z",
          "ewallet": null,
          "qr_code": null,
          "updated": "2022-08-12T13:30:40.221525Z",
          "metadata": null,
          "description": null,
          "reusability": "MULTIPLE_USE",
          "direct_debit": {
              "type": "BANK_ACCOUNT",
              "debit_card": null,
              "bank_account": {
                  "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                  "masked_bank_account_number": "XXXXXX1234"
              },
              "channel_code": "BPI",
              "channel_properties": {
                  "failure_return_url": "https://your-redirect-website.com/failure",
                  "success_return_url": "https://your-redirect-website.com/success"
              }
          },
          "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
          "virtual_account": null,
          "over_the_counter": null,
          "direct_bank_transfer": null
      },
      "description": null,
      "failure_code": "INSUFFICIENT_BALANCE",
      "payment_detail": null,
      "channel_properties": null,
      "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
  },
  "created": "2022-08-12T13:30:58.986Z",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
MAX_OTP_ATTEMPTS_ERROR
The maximum incorrect attempts allowed by the channel has been reached.
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.

E-Wallets

Account Linking (E-Wallets)

Account linking in tokenized eWallet refers to end user authorizing merchants to perform transactions via a token (linking) for the end user's eWallet (account). This endpoint starts the authorization process and a payment method will be created as a result. End users need to be redirected to the eWallet provider's hosted page to authorize the account linking. Once the account linking is completed by the end user, an account linking notification will be sent to the callback url specified in the Xendit dashboard under payment methods section.

The table below summarizes key onboarding information of these tokenization payment flow. By default, all tokenization flow requires approval with eWallet partners. Auto debit flows which require special approval will require escalation to the eWallet partners before merchants can access the feature.

Indonesia

Value OVO DANA LINKAJA SHOPEEPAY
Redirection (PIN required) payment
Approval required Approval required Approval required Approval required
Auto debit payment
Special approval required Special approval required โœ• Special approval required

Philippines

Value SHOPEEPAY MAYA (PAYMAYA) GRABPAY GCASH
Auto debit payment
Approval required Approval required Approval required Approval required

Malaysia

Value TOUCHNGO SHOPEEPAY GRABPAY
Auto debit payment
Approval required Approval required Approval required

Endpoint: Account Linking - Create Payment Method

POST https://api.xendit.co/v2/payment_methods

Account Linking - Create Payment Method Request

Example Account Linking - Create Payment Method Request

curl https://api.xendit.co/v2/payment_methods -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "type": "EWALLET",
      "reusability": "MULTIPLE_USE",
      "ewallet": {
        "channel_code": "OVO",
        "channel_properties": {
          "success_return_url": "https://your-redirect-website.com/success",
          "failure_return_url": "https://your-redirect-website.com/failure"
        }
      },
      "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde"
}' \
{
  "type": "EWALLET",
  "reusability": "MULTIPLE_USE",
  "ewallet": {
    "channel_code": "OVO",
    "channel_properties": {
      "success_return_url": "https://your-redirect-website.com/success",
      "failure_return_url": "https://your-redirect-website.com/failure"
    }
  },
  "customer_id": "fc4c060b-3c41-4707-b7b2-df9c3376edde"
}



Request Body Parameter Type Description
type
required
string Type of payment method - to use EWALLET as value
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

use MULTIPLE_USE as value for eWallets account linking
customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Tokenized - Create Customer to generate Customer ID
customer
optional
object A customer object to skip Create Customer URL endpoint process. This object is required for all if the customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL
individual_detail
conditional
object JSON object containing details of the individual.
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH for Philippines, ID for Indonesia, MY for Malaysia
reference_id
optional
string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
description
optional
string Free-text field for any additional information regarding the payment method
metadata
optional
string A free-format JSON for additional information that you may use
ewallet
required
object For type='EWALLET', this contains the necessary information to describe an ewallet payment method

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported eWallets and their channel codes:
  • DANA
  • OVO
  • LINKAJA
  • SHOPEEPAY
  • GRABPAY
  • PAYMAYA
  • GCASH
  • TOUCHNGO
channel_properties
required
object Object that contains the required information to perform account linking with eWallet account for payments
OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GCASH, GRABPAY (PH & MY) and TOUCHNGO required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
MAYA (PAYMAYA) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
required
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes

Account Linking - Create Payment Method Response

Example Account Linking - Create Payment Method Success Response

{
    "id": "pm-123123123-f4d9-421c-9f0b-ab3b2b6bbc39",
    "type": "EWALLET",
    "country": "ID",
    "business_id": "5f27a14a9bf05c73123123123",
    "customer_id": "fc4123123-3c41-4707-b7b2-df9c3376edde",
    "reference_id": "b63798d3-8240-48c3-af12-3b3c62c0981a",
    "reusability": "MULTIPLE_USE",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://link-web.xendit.co/auth/lat-bcf19cc8-f097-44fb-839c-6e4aed807d00/confirm",
            "url_type": "WEB",
            "method": "GET"
        }
    ],
    "description": null,
    "created": "2021-08-18T03:52:56.936277373Z",
    "updated": "2021-08-18T03:52:56.936277373Z",
    "metadata": {
        "sku": "IPHONE20"
    },
    "ewallet": {
        "channel_code": "OVO",
        "channel_properties": {
            "failure_return_url": "https://your-redirect-website.com/failure",
            "success_return_url": "https://your-redirect-website.com/success"
        },
        "account": {
            "name": null,
            "account_details": null,
            "balance": null,
            "point_balance": null
        }
    },
    "direct_bank_transfer": null,
    "direct_debit": null,
    "card": null,
    "over_the_counter": null,
    "qr_code": null,
    "virtual_account": null
}
Body Parameter Type Description
id
required
string Unique identifier for the payment method. This has a prefix of pm-. Example: pm-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
type
required
string Type of payment method - to use EWALLET as value
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments without going through the same linking process again.

use MULTIPLE_USE as value for eWallets
customer_id
required
string ID of the customer object to which the account token will be linked to. Call Tokenized - Create Customer to generate Customer ID
business_id
required
string Xendit-generated identifier for the business that owns the transaction
reference_id
optional
string Merchant-provided identifier for this payment method. If none is provided, Xendit will randomly generate a unique reference_id
status
required
string Status of the payment method. Allowed values - PENDING, REQUIRES_ACTION, ACTIVE, INACTIVE, EXPIRED

REQUIRES_ACTION - The request passed validation but requires additional steps in order to activate the payment method for use. Typical actions are for merchant to trigger OTP validation or redirect your customer to authentication page.
ACTIVE - The payment method can be used for payment requests.
INACTIVE - Merchant performing unlinking on payment method will trigger this status. This status prevents further transactions from the payment method and is reversible.
EXPIRED - The underlying authorization has expired, invalidated, or has been unlinked. This status is not reversible
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. shopeepay). Available values - PH, ID, MY
actions
required
object If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to activate a payment method
Key Value
method
required
string HTTP method for calling the url. Allowed values: GET, POST
url_type
required
string Type of url for the specific action.
API - The provided url is a server-side API, merchant will need to provide necessary information to the API
WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string AUTH - Trigger this action in order to authorize linking or payment.
RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer
url
required
string The generated URL to hit in order to perform the action
ewallet
required
object For type='EWALLET', this contains the necessary information to describe an ewallet payment method
Key Value
channel_code
required
string Identifier for the payment channel partner
Supported eWallets and their channel codes:
  • DANA
  • OVO
  • LINKAJA
  • SHOPEEPAY
  • GRABPAY
  • PAYMAYA
  • GCASH
  • TOUCHNGO
channel_properties
required
object Object that contains the required information to perform account linking with eWallet account for payments
OVO, DANA, LINKAJA, SHOPEEPAY (ID, PH & MY), GCASH, GRABPAY (PH & MY) and TOUCHNGO required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
MAYA (PAYMAYA) required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
cancel_return_url
required
string URL where the end-customer is redirected if the authorization has been cancelled. End-customer can retry payment on the same link within 15 minutes

account
optional
object Object that contains information of the linked eWallet account
Key Value
account_details
optional
string Masked public identifier for the eWallet account. This typically contains the masked mobile number registered to the eWallet account. This will be null if unavailable
name
optional
string Name of the eWallet account holder. This will be null if unavailable
balance
optional
number Current available balance in the eWallet. This will be null if unavailable
point_balance
optional
number Current available points in the eWallet for consumption. This will be null if unavailable
created
required
string ISO 8601 Timestamp for charge object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest charge object update. Timezone UTC+0
description
optional
object Free-text field for any additional information regarding the payment method
metadata
optional
object User defined object with JSON properties and values passed in during charge creation.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long

Account Linking - Create Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the required request fields
INVALID_API_KEY
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Payment request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
Xendit code specifying the error encountered: There's an already existing record with the provided details
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
CUSTOMER_NOT_FOUND_ERROR
400
Provided customer_id in the request parameters does not exist / owned by a different business / invalid format
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account to be linked has been blocked by the partner channel
INVALID_ACCOUNT_DETAILS
400
The provided details for account linking in incorrect or has been rejected by the partner channel
FORBIDDEN
403
Provided API key does not have the correct permissions to perform the operation
IDEMPOTENCY_ERROR
403
The request body does not match the body of the previous request with the same Idempotency key
SERVER_ERROR
403
An error occurred on Xendit's side

Webhook Account Linking Activated (E-Wallets)

This callback is triggered when a particular Payment Method has been successfully created and can be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{
    "id": "pm-947ad717-c346-4fbd-8a30-c37ae3421a78",
    "data": {
        "id": "pm-947ad717-c346-4fbd-8a30-c37ae3421a78",
        "card": null,
        "type": "EWALLET",
        "status": "ACTIVE",
        "actions": [],
        "country": "ID",
        "created": "2023-05-31T09:37:53.643369Z",
        "ewallet": {
            "account": {
                "name": "John  Doe",
                "balance": null,
                "point_balance": null,
                "account_details": "+62123456XXXX"
            },
            "channel_code": "OVO",
            "channel_properties": {
                "failure_return_url": "https://redirect.me/badstuff",
                "success_return_url": "https://redirect.me/goodstuff"
            }
        },
        "qr_code": null,
        "updated": "2023-05-31T09:38:04.697488975Z",
        "metadata": {
            "foo": "bar"
        },
        "business_id": "628db55f8378fa6f14db977f",
        "customer_id": "cust-97400c09-714f-41a2-9a0a-1325ab4e9ab9",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": null,
        "failure_code": null,
        "reference_id": "b3155b96-c8bb-4a8b-96ae-75c21caab607",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "event": "payment_method.activated",
    "created": "2023-05-31T09:38:04.930873409Z",
    "business_id": "628db55f8378fa6f14db977f"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

Tokenized Payment E-Wallets

This endpoint provides the scenario where your End-customer want to have a linking scenario first then make a payment scenario subsequently. For this scenarion, Create Ewallet Account linking is required as pre-requisite, where the payment method ID (pm-xx) will be required for this create payment request.

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 1500,
    "currency": "PHP",
    "payment_method_id": "pm-04152d03-0f56-433c-994c-251f79b6074a",
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.

Request Body Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • MYR
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
country
conditional
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method_id
required
object Note: Only one of payment_method{} or payment_method_id must be present.
ID of the ACTIVE Payment Method to be used in the payment.
channel_properties
optional
object Specific settings to be applied to the transaction. This also overwrites any common parameters with the Payment Method Object.
For multiple use OVO, and SHOPEEPAY (ID & MY):
Key Value
redeem_points
nullable
string Indicates whether or not to use the Payment Method's points_balance in the transaction
Possible values:
  • REDEEM_NONE - No points will be used
  • REDEEM_ALL - points will be used to offset payment amount before cash balance is used.
    REDEEM_ALL can only be used when approved by OVO for promotions.
    For SHOPEEPAY (ID), only up to 50% of the transaction amount (rounded down) can be paid using SHOPEEPAY coins.
Default value: REDEEM_NONE
success_return_url
nullable
string URL where the end-customer is redirected if the authorization is successful

For GRABPAY (MY):
Key Value
allowed_payment_options
optional
Array of enums
  • PAYLATER_POSTPAID - Pay next month
  • PAYLATER_INSTALLMENTS_4MO - Pay with installments

Choose One payment option to use, default will use GrabPay Ewallet balance

metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490",
    "country": "ID",
    "amount": 1500,
    "currency": "IDR",
    "business_id": "628db55f8378fa6f14db977f",
    "reference_id": "b7179cb7-33ed-4459-8482-42f1c2fb03aa",
    "payment_method": {
        "id": "pm-04152d03-0f56-433c-994c-251f79b6074a",
        "type": "EWALLET",
        "reference_id": "60288a67-6f0d-4399-8e29-cb5fd42b6a3b",
        "description": null,
        "created": "2023-07-18T02:17:06.916218Z",
        "updated": "2023-07-18T02:19:37.110908Z",
        "card": null,
        "ewallet": {
            "channel_code": "OVO",
            "channel_properties": {
                "cancel_return_url": "https://redirect.me/nostuff",
                "failure_return_url": "https://redirect.me/badstuff",
                "success_return_url": "https://redirect.me/goodstuff"
            },
            "account": {
                "name": "John  Doe",
                "account_details": "+62123456XXXX",
                "balance": 1000000,
                "point_balance": 1000000
            }
        },
        "direct_debit": null,
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": {
            "foo": "bar"
        },
        "reusability": "MULTIPLE_USE",
        "status": "ACTIVE"
    },
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    },
    "customer_id": "cust-bac23581-7fef-49e6-8074-c2aeb022df3b",
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-18T02:23:57.5780025Z",
    "updated": "2023-07-18T02:23:57.5780025Z",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://ewallet-mock-connector.xendit.co/v1/ewallet_connector/checkouts?token=ciqvffj78onc0bue8uig",
            "url_type": "WEB",
            "method": "GET",
            "qr_code": null
        },
        {
            "action": "AUTH",
            "url": "https://ewallet-mock-connector.xendit.co/v1/ewallet_connector/checkouts?token=ciqvffj78onc0bue8uig",
            "url_type": "MOBILE",
            "method": "GET",
            "qr_code": null
        }
    ],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
PROCESSOR_CONFIGURATION_ERROR
500
Payment declined due to a problem with the merchant configuration on the Card Processor. Contact Xendit to troubleshoot the issue.
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
PROCESSOR_TEMPORARILY_UNAVAILABLE
503
The Card Processor appears to be temporarily unavailable. Wait for a couple minutes, then resend the request. If it fails again, Cardholder can try using a different card or other form of payment.
PROCESSOR_TIMEOUT_ERROR
503
Request was received by the processor, but there was a server timeout. Wait for a couple minutes and then retry the request.
INSUFFICIENT_BALANCE
400
Source of funds has insufficient balance to complete the transaction
MAX_AMOUNT_LIMIT_ERROR
400
The transaction amount exceeds the partner channel's set limits
INVALID_PAYMENT_METHOD
400
The provided payment method id has already expired or is inactive
ACCOUNT_NOT_ACTIVATED
400
End-customer's account is not activated for payments.
CUSTOMER_UNREACHABLE
400
The end-user's device cannot be reached at this moment

Webhook Payment Succeeded Ewallet Tokenized

This is also send for successful Payment Requests for EWALLET, DIRECT_DEBIT, and CARD.

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "created": "2023-05-31T09:38:35.559Z",
    "business_id": "628db55f8378fa6f14db977f",
    "event": "payment.succeeded",
    "data": {
        "id": "ewc_f7035bb6-5b62-4c43-b8d3-c80955554e01",
        "items": null,
        "amount": 1500,
        "status": "SUCCEEDED",
        "country": "ID",
        "created": "2023-05-31T09:38:17.664697Z",
        "updated": "2023-05-31T09:38:32.975311Z",
        "currency": "IDR",
        "metadata": {
            "foo": "bar"
        },
        "customer_id": "cust-97400c09-714f-41a2-9a0a-1325ab4e9ab9",
        "description": "This is a description.",
        "failure_code": null,
        "reference_id": "729308f7-741c-4e87-af84-6abc5e67f212",
        "payment_detail": null,
        "payment_method": {
            "id": "pm-947ad717-c346-4fbd-8a30-c37ae3421a78",
            "card": null,
            "type": "EWALLET",
            "status": "ACTIVE",
            "created": "2023-05-31T09:37:53.643369Z",
            "ewallet": {
                "account": {
                    "name": "John  Doe",
                    "balance": 1000000,
                    "point_balance": 1000000,
                    "account_details": "+62123456XXXX"
                },
                "channel_code": "OVO",
                "channel_properties": {
                    "failure_return_url": "https://redirect.me/badstuff",
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "qr_code": null,
            "updated": "2023-05-31T09:38:04.697489Z",
            "metadata": {
                "foo": "bar"
            },
            "description": null,
            "reusability": "MULTIPLE_USE",
            "direct_debit": null,
            "reference_id": "b3155b96-c8bb-4a8b-96ae-75c21caab607",
            "virtual_account": null,
            "over_the_counter": null,
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-b89ff299-1c4a-454e-b9f0-a8435e6ddcf8"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

Webhook Payment Failed Ewallet Tokenized

Note: Make sure that you ONLY have a callback URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate callbacks, DO NOT fill out product-specific sections.

Callback Payload

Example: Payment Failed Callback Payload

{
    "created": "2023-05-31T10:11:02.966Z",
    "business_id": "628db55f8378fa6f14db977f",
    "event": "payment.failed",
    "data": {
        "id": "ewc_a34d616a-0885-49ff-a0d4-6ea3e3c974e2",
        "items": null,
        "amount": 20103,
        "status": "FAILED",
        "country": "ID",
        "created": "2023-05-31T10:09:16.650076Z",
        "updated": "2023-05-31T10:11:02.600413Z",
        "currency": "IDR",
        "metadata": null,
        "customer_id": null,
        "description": null,
        "failure_code": "ACCOUNT_ACCESS_BLOCKED",
        "reference_id": "fd6bec13-be0f-44c4-9f7b-cd5608dc1147",
        "payment_detail": null,
        "payment_method": {
            "id": "pm-72e1e315-2455-4b57-b7ea-606a0e469c00",
            "card": null,
            "type": "EWALLET",
            "status": "EXPIRED",
            "created": "2023-05-31T10:09:16.560672Z",
            "ewallet": {
                "account": {
                    "name": null,
                    "balance": null,
                    "point_balance": null,
                    "account_details": null
                },
                "channel_code": "SHOPEEPAY",
                "channel_properties": {
                    "success_return_url": "https://redirect.me/goodstuff"
                }
            },
            "qr_code": null,
            "updated": "2023-05-31T10:09:16.560672Z",
            "metadata": null,
            "description": null,
            "reusability": "MULTIPLE_USE",
            "direct_debit": null,
            "reference_id": "90c17ae5-029b-4f14-bd90-8d0df6415cc1",
            "virtual_account": null,
            "over_the_counter": null,
            "billing_information": {
                "city": null,
                "country": "",
                "postal_code": null,
                "street_line1": null,
                "street_line2": null,
                "province_state": null
            },
            "direct_bank_transfer": null
        },
        "channel_properties": null,
        "payment_request_id": "pr-f436fdc8-8dbf-46ec-b498-baa6d714464f"
    },
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
MAX_OTP_ATTEMPTS_ERROR
The maximum incorrect attempts allowed by the channel has been reached.
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.

Webhook Account Linking Expired (E-Wallets)

This callback is triggered when a particular Payment Method has expired and will be unusable for payment transactions.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Expired Callback Payload

{
    "id": "pm-62e521fc-09bd-4d50-bc44-a190c482a1a5",
    "data": {
        "id": "pm-62e521fc-09bd-4d50-bc44-a190c482a1a5",
        "card": null,
        "type": "EWALLET",
        "status": "EXPIRED",
        "actions": [],
        "country": "ID",
        "created": "2023-05-31T08:17:40.084679Z",
        "ewallet": {
            "account": {
                "name": null,
                "balance": null,
                "point_balance": null,
                "account_details": null
            },
            "channel_code": "SHOPEEPAY",
            "channel_properties": {
                "success_return_url": "https://redirect.me/goodstuff"
            }
        },
        "qr_code": null,
        "updated": "2023-05-31T08:18:13.355204166Z",
        "metadata": null,
        "business_id": "628db55f8378fa6f14db977f",
        "customer_id": null,
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": null,
        "failure_code": null,
        "reference_id": "6c8ad38e-2925-44c4-95af-35003298eefa",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "street_line1": null,
            "street_line2": null,
            "province_state": null
        },
        "direct_bank_transfer": null
    },
    "event": "payment_method.expired",
    "created": "2023-05-31T08:18:13.587592978Z",
    "business_id": "628db55f8378fa6f14db977f"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.expired
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status EXPIRED

Link and Pay Scenario

This flow simplifies checkout payments for guest users, especially for direct debit cases, while also offering the option for the end customer to save the payment method for future use.

Direct Debit Link and Pay

This flow is ideal for situations where you want to offer a checkout payment option, allowing your customers to save it for future payments.

After making the following payment, the next task is to verify it using an OTP (One-Time Password). For this flow, you may need to use xendit hosted OTP given in action parameter in the response.

Once the payment sucessful, then the payment method status will be Active means the account has be linked and you can use the payment method ID as tokenized payment for the subsequent payment. The tokenized payment details can be found in here

Endpoint: Create Payment Request

POST https://api.xendit.co/payment_requests

Create Payment Request Request

Example Create Payment Request Request

curl https://api.xendit.co/payment_requests -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
    "amount": 500,
    "currency": "PHP",
    "payment_method": {
        "type": "DIRECT_DEBIT",
        "direct_debit": {
            "channel_code": "BPI",
            "channel_properties": {
                "success_return_url" : "https://redirect.me/goodstuff",
                "failure_return_url" : "https://redirect.me/badstuff"
            }
        },
        "reusability": "MULTIPLE_USE"
    },
    "customer_id": "cust-1e68806c-38d7-4109-b1cd-4f10ef4cf99b",
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    }
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
with-split-rule
optional
string Split Rule ID that you would like to apply to this Payment Request in order to split and route payments to multiple accounts.

Please note: If you include this parameter, we will return the split_rule_id in the header of the API response.

If for-user-id header is not present, Split Rule will still be routed from platform account to the specified destination account

Please note that this is the newest header version, the older version with-fee-rule header will be deprecated by September 30, 2025. Please migrate to this version before the the deprecation date if you are still using with-fee-rule header.

This header is only used if you have access to xenPlatform. See xenPlatform for more information.



Parameter Type Description
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Accepted values:
  • IDR
  • PHP
  • THB
  • MYR
amount
required
number Expected and accepted amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.

reference_id
optional
string Merchant-provided identifier for this payment request.
If none is provided, Xendit will randomly generate a unique reference_id.


Maximum length: 255 characters
customer_id
conditional
string ID of the customer object to which the account token will be linked to. Call Create Customer to generate Customer ID.

A customer_id is required for all DIRECT_DEBIT payment methods and if the customer object is null.
customer
conditional
object A customer object to skip Create Customer URL endpoint process. This object only available if customer_id is null.

The parameters to be set for the customer object
Key Value
reference_id
required
string Merchant-provided identifier for the customer
type
required
string Type of customer. Supported values: INDIVIDUAL, BUSINESS
individual_detail
conditional
object JSON object containing details of the individual. Will be null if type is not INDIVIDUAL
Key Value
given_names
required
string Primary or first name/s of customer
surname
optional
string Last or family name of customer
nationality
optional
string Country code for customer's nationality
place_of_birth
optional
string City or other relevant location for the customerโ€™s birth place.
date_of_birth
optional
string Date of birth of the customer
gender
optional
string Gender of customer. Supported values: MALE,FEMALE,OTHER
email
optional
string E-mail address of customer. Maximum length 50 characters
mobile_number
optional
string Mobile number of customer in E.164 format

Maximum length 50 characters
country
optional
string 2-letter ISO 3166-2 country code indicating country of transaction.

Accepted values:
  • ID - Indonesia
  • PH - Philippines
  • TH - Thailand
  • MY - Malaysia
description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
conditional
object Note: Only one of payment_method{} or payment_method_id must be present.
Respective Payment Method properties that corresponds to the chosen payment method type or channel.
The request will apply the top-most values for customer_id, currency, and amount.

The parameters to be set for the payment method object
Key Value
type
required
string Type of payment method
For Direct debit:
  • DIRECT_DEBIT
reusability
required
string Describes whether or not the payment method can be reused for subsequent payments.

For DIRECT_DEBIT, this determines whether or not authentication is performed again for subsequent payments.

Accepted values for one time case: MULTIPLE_USE
reference_id
optional
string Merchant-provided identifier for this payment method.
If none is provided, Xendit will randomly generate a unique reference_id.


description
optional
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
metadata
optional
object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.
direct_debit
required
object Required for type='DIRECT_DEBIT', this contains the necessary information to describe a direct debit payment method.

Key Value
channel_code
required
string Identifier for the payment channel partner
Supported banks and their channel codes: refer to this section
channel_properties
required
object Object that contains the required information to perform payments using direct debit

BRI Direct Debit required fields
Key Value
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
card_last_four
required
string Last four digits of the debit card
card_expiry
optional
string Expiry month and year of the debit card (in MM/YY format)
email
required
string Email address of the customer that is registered to the partner channel

MANDIRI, BPI, UBP, RCBC, CHINABANK, and FPX Channels under Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
SCB and BBL Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
KTB and BAY Direct Debit required fields
Key Value
success_return_url
required
string URL where the end-customer is redirected if the authorization is successful
failure_return_url
required
string URL where the end-customer is redirected if the authorization failed
mobile_number
required
string Registered mobile number of the end-customer to the channel partner in E.164 Format.
identity_document_number
required
number The account holder's ID Card number or passport number.

metadata
optional
object object A free-format JSON for additional information that you may use.
Object can be up to 50 keys, with key names up to 40 characters long and values up to 500 characters long.

Create Payment Request Response

Example Create Payment Request Response

{
    "id": "pr-8f9a5d3a-0f9f-47bf-8452-a4be9388b490",
    "country": "PH",
    "amount": 500,
    "currency": "PHP",
    "business_id": "6396e6d48c59c18ca0e55218",
    "reference_id": "eeaf6501-dea4-4103-bb7e-8ee706ce04f6",
    "payment_method": {
        "id": "pm-02318afc-9810-4044-b8b4-d0eacb0a77a8",
        "type": "DIRECT_DEBIT",
        "reference_id": "54ee6999-a032-40c6-b731-dcc7f6d26040",
        "description": null,
        "created": "2023-07-16T22:38:13.474210828Z",
        "updated": "2023-07-16T22:38:13.474210828Z",
        "card": null,
        "ewallet": null,
        "direct_debit": {
            "channel_code": "BPI",
            "channel_properties": {
                "success_return_url": "https://redirect.me/goodstuff",
                "failure_return_url": "https://redirect.me/badstuff"
            },
            "type": "BANK_ACCOUNT",
            "bank_account": {
                "masked_bank_account_number": null,
                "bank_account_hash": null
            },
            "debit_card": null
        },
        "direct_bank_transfer": null,
        "over_the_counter": null,
        "virtual_account": null,
        "qr_code": null,
        "metadata": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "province_state": null,
            "street_line1": null,
            "street_line2": null
        },
        "reusability": "MULTIPLE_USE",
        "status": "PENDING"
    },
    "description": "This is a description.",
    "metadata": {
        "foo": "bar"
    },
    "customer_id": "cust-bf61e185-da02-4223-a594-5da05c45218e",
    "capture_method": "AUTOMATIC",
    "initiator": null,
    "card_verification_results": null,
    "created": "2023-07-16T22:38:13.231458108Z",
    "updated": "2023-07-16T22:38:13.231458108Z",
    "status": "REQUIRES_ACTION",
    "actions": [
        {
            "action": "AUTH",
            "url": "https://link-web-staging.xendit.co/oauth/lat-17702cc1-31c8-4791-b243-8699a3575146/confirm",
            "url_type": "WEB",
            "method": "GET",
            "qr_code": null
        }
    ],
    "failure_code": null,
    "channel_properties": null,
    "shipping_information": null,
    "items": null
}

A successful Payment Request creation returns a Payment Request Object with an HTTP 201 status code.
Listen to the payment.* callbacks for the final status of the transaction.


Body Parameter Type Description
id
required
string Unique identifier for the payment request. This has a prefix of pr-. Example: pr-6d1c8be4-f4d9-421c-9f0b-ab3b2b6bbc39
business_id
required
string Xendit-generated identifier for the business that owns the transaction
customer_id
nullable
string ID of the customer object to which the account token will be linked to
reference_id
nullable
string Identifier provided by the merchant or automatically generated by Xendit if it was not provided.
Maximum length: 255 characters
currency
required
string ISO 4217 three-letter code of the transaction's currency. Will be auto-filled based on the channel_code if not provided.
Possible values:
  • IDR
  • PHP
  • THB
  • MYR
  • VND
amount
nullable
number Authorized amount of the transaction in the actual value in the provided currency.
Decimal places support varies per currency:
  • IDR - Only supports positive integers.
  • PHP - Supports up to two decimal places.
  • THB - Supports up to two decimal places.
  • MYR - Supports up to two decimal places.
  • VND - Only supports positive integers.

If amount is not provided, the corresponding payment method will accept any amount as payment (open amount). (Applicable only for OVER_THE_COUNTER and VIRTUAL_ACCOUNT)
country
required
string 2-letter ISO 3166-2 country code indicating country of transaction. This is also be used as indicator for channels that are present in multiple markets (e.g. SHOPEEPAY).
status
required
string Status of the payment method.

Possible values:
  • REQUIRES_ACTION - The request passed validation but requires additional steps in order to complete the payment. Typical actions are for merchant to trigger OTP validation or redirect your customer to an authentication page.
  • PENDING - The transaction passed initial validation and the payment channel is currently processing the transaction.
description
nullable
string Free-text field for any additional information regarding the payment method.
Maximum length: 255 characters
payment_method
required
object Corresponding Payment Method created or used for the Payment Method.
Note: customer_id, currency, and amount are moved to the root level of the Payment Request object.
actions
required
object array If status=REQUIRES_ACTION, this contains objects that detail the possible next steps in order to complete a payment. Only one of the provided actions is required to be fulfilled. If no further action is needed, this parameter will be an empty array [].

Each object will have the following properties:
Key Value
method
required
string HTTP method for calling the url.

Possible values:
  • GET
  • POST
url_type
required
string Type of url for the specific action.

Possible values:
  • API - The provided url is a server-side API, merchant will need to provide necessary information to the API
  • WEB - The provided redirect url is optimized for desktop or web interface. This can also be used if no MOBILE url is provided. Merchant will need to redirect their end user to this page to complete payment authentication.
  • MOBILE - The provided redirect url is optimized for mobile devices. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
  • DEEPLINK - The provided redirect url utilizes deep linking to the channel partnerโ€™s platform. Merchant will need detect the mobile device and redirect their end user to this page to complete payment authentication.
action
required
string Describes the purpose the corresponding action

Possible values:
  • AUTH - Trigger this action in order to authorize linking or payment.
  • RESEND_AUTH - Trigger this action in order to resend the authorization code to the end-customer.
url
required
string The generated URL to hit in order to perform the action
failure_code
nullable
string If the status of the transaction is FAILED, this describes the reason for failure.
Will be null if the transaction did not fail.
See possible codes here.
created
required
string ISO 8601 Timestamp for Payment Request object creation. Timezone UTC+0
updated
required
string ISO 8601 Timestamp for latest Payment Request object update. Timezone UTC+0
metadata
nullable
object User defined object with JSON properties and values passed in during Payment Request creation.

Create Payment Request Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
CUSTOMER_NOT_FOUND_ERROR
400
The provided customer_id does not exist.
CUSTOMER_PAYMENT_METHOD_MISMATCHED
400
Error due to the customer_id provided does not have access to the provided payment method information
INVALID_ACCOUNT_DETAILS
400
The provided details were rejected by the partner channel due to incorrect information.
INVALID_PAYMENT_METHOD
400
The provided payment_method_id has already expired or is inactive
MAX_ACCOUNT_LINKING
400
The direct debit account being attempted to be linked has reached the maximum linking allowed by the partner channel.
PARTNER_CHANNEL_ERROR
400
Error received from partner channel but no reasons provided
INVALID_API_KEY
401
API key format is invalid
INVALID_MERCHANT_CREDENTIALS
401
API key format is invalid
CHANNEL_NOT_ACTIVATED
403
Request failed because this specific payment channel has not been activated through Xendit. Please activate via Xendit dashboard or our customer service
FEATURE_NOT_ACTIVATED
403
A certain feature being accessed has not yet activated. Please reach out to our customer service for further assistance.
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
DUPLICATE_ERROR
409
There's an already existing record with the provided details
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The provider will be notified to resolve this issue
OTP_DELIVERY_ERROR
503
The partner channel has failed to send the OTP to the Customer
PROCESSOR_ERROR
503
General system failure returned by the Card processor. Retry the request again after couple of minutes.
INSUFFICIENT_BALANCE
400
Source of funds has insufficient balance to complete the transaction.
MAX_AMOUNT_LIMIT_ERROR
400
The transaction amount exceeds the partner channel's set limits.
FORBIDDEN
403
Provided API key does not have the correct permissions to perform the operation.

This endpoint only applies to BRI Direct Debit. This is used when an additional authorization (ex. OTP Validation) is required in order to successfully activate a payment method. This is equivalent to the POST - AUTH action provided when a Payment Method has the status REQUIRES_ACTION.

Endpoint: Account Linking - Authorize Payment Method

POST https://api.xendit.co/v2/payment_methods/:id/auth

Authorize Payment Method Request

Example Account Linking - Authorize Payment Method Request

curl https://api.xendit.co/v2/payment_methods/pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a/auth -X POST \
   --user xnd_development_LoReMIPman+ZPGT+ZZ9b3ooF4w3Dn+R1k+LoReMIPman: \
   --header 'Content-Type: application/json' \
   --data-raw '{
      "auth_code": "356443"
}' \
Header Type Description
idempotency-key
optional
string Provided to prevent duplicate requests. Can be equal to any UUID. Idempotency keys are stored on the request layer; it expires after 24 hours from the first request. Note: Max 100 characters
for-user-id
optional
string The sub-account user-id that you want to make this transaction for.

This header is only used if you have access to xenPlatform. See xenPlatform for more information
Path Parameter Type Description
id
required
string Primary identifier for the Payment Method object. This starts with the prefix pm-.
Request Body Parameter Type Description
auth_code
required
string The authorization code or OTP inputted by the end-customer.

Authorize Payment Method Response

Example Account Linking - Authorize Payment Method Success Response

{
  "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
  "card": null,
  "type": "DIRECT_DEBIT",
  "status": "ACTIVE",
  "actions": [],
  "country": "ID",
  "created": "2022-08-12T13:30:26.579048Z",
  "ewallet": null,
  "qr_code": null,
  "updated": "2022-08-12T13:30:58.908220358Z",
  "metadata": null,
  "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
  "description": null,
  "reusability": "MULTIPLE_USE",
  "direct_debit": {
      "type": "DEBIT_CARD",
      "debit_card": {
        "mobile_number": "+62818555988",
            "card_last_four": "8888",
            "card_expiry": "06/24",
            "email": "email@email.com"
      },
      "bank_account": null,
      "channel_code": "BRI",
      "channel_properties": {
          "mobile_number": "+62818555988",
          "card_last_four": "8888",
          "card_expiry": "06/24",
          "email": "test.email@xendit.co"
      }
  },
  "failure_code": null,
  "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
  "virtual_account": null,
  "over_the_counter": null,
  "billing_information": null,
  "direct_bank_transfer": null,
  "business_id": "5f27a14a9bf05c73dd040bc8"
}

Returns a Payment Method Object with an HTTP 200 status code.

Authorize Payment Method Errors

Error Code Description
API_VALIDATION_ERROR
400
There is invalid input in one of the request fields or a required field was not filled out
ACCOUNT_ACCESS_BLOCKED
400
Access to the underlying account or card has been blocked by the partner channel or the issuer.
EXPIRED_OTP_ERROR
400
The provided auth_code has expired
INVALID_OTP_ERROR
400
The provided auth_code is incorrect
MAX_OTP_ATTEMPTS_ERROR
400
The maximum attempts allowed by the channel has been reached
INVALID_API_KEY
401
API key format is invalid
REQUEST_FORBIDDEN_ERROR
403
The API key is forbidden to perform this request
FEATURE_NOT_SUPPORTED
403
A certain feature being accessed is not supported
DATA_NOT_FOUND
404
The provided id did not match any of our records
IDEMPOTENCY_ERROR
409
The same Idempotency-key was provided with a different payload
PAYMENT_METHOD_ALREADY_ACTIVE
409
Cannot proceed because the payment method is already active or has been activated
PAYMENT_METHOD_ALREADY_FAILED
409
Cannot proceed because the payment method has failed authorization and cannot be retried
SERVER_ERROR
500
An unexpected error occured, our team has been notified and will troubleshoot the issue
CHANNEL_UNAVAILABLE
503
The payment channel requested is currently experiencing unexpected issues. The eWallet provider will be notified to resolve this issue

This callback is triggered when a particular Payment Method has been successfully created and can be used for payments.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Activated Callback Payload

{

    "event": "payment_method.activated",
    "data": {
        "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "ACTIVE",
        "actions": [],
        "country": "PH",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:58.908220358Z",
        "metadata": null,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                "masked_bank_account_number": "XXXXXX1234"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            }
        },
        "failure_code": null,
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "created": "2022-08-12T13:30:59.074277334Z",
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.activated
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status ACTIVE

This callback is triggered when a particular Payment Method has expired and will be unusable for payment transactions.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Expired Callback Payload

{
    "event": "payment_method.expired",
    "data": {
        "id": "pm-6ff0b6f2-f5de-457f-b08f-bc98fbae485a",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "EXPIRED",
        "actions": [],
        "country": "PH",
        "created": "2022-08-12T13:30:26.579048Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2022-08-12T13:30:58.908220358Z",
        "metadata": null,
        "customer_id": "e2878b4c-d57e-4a2c-922d-c0313c2800a3",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                "masked_bank_account_number": "XXXXXX1234"
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://your-redirect-website.com/failure",
                "success_return_url": "https://your-redirect-website.com/success"
            }
        },
        "failure_code": null,
        "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": null,
        "direct_bank_transfer": null
    },
    "created": "2022-08-12T13:30:59.074277334Z",
    "business_id": "5f27a14a9bf05c73dd040bc8"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.expired
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status EXPIRED

This callback is triggered when a particular Payment Method has failed during authentication/authorization.

Note: Make sure that you have a callback URL registered in the Payment Method field in your Dashboard settings.

Callback Payload

Example: Payment Method Failed Callback Payload

{
    "id": "pm-02aa112e-ac69-448a-bab9-0f216fc512d0",
    "data": {
        "id": "pm-02aa112e-ac69-448a-bab9-0f216fc512d0",
        "card": null,
        "type": "DIRECT_DEBIT",
        "status": "FAILED",
        "actions": [],
        "country": "PH",
        "created": "2023-08-10T10:48:38.600369Z",
        "ewallet": null,
        "qr_code": null,
        "updated": "2023-08-10T10:48:50.389414006Z",
        "metadata": null,
        "business_id": "6396e6d48c59c18ca0e55218",
        "customer_id": "cust-5d360bbb-3aa7-4cc0-8d8f-c9e58af2be81",
        "description": null,
        "reusability": "MULTIPLE_USE",
        "direct_debit": {
            "type": "BANK_ACCOUNT",
            "debit_card": null,
            "bank_account": {
                "bank_account_hash": null,
                "masked_bank_account_number": null
            },
            "channel_code": "BPI",
            "channel_properties": {
                "failure_return_url": "https://redirect.me/badstuff",
                "success_return_url": "https://redirect.me/goodstuff"
            }
        },
        "failure_code": "PAYMENT_METHOD_ALREADY_EXISTS",
        "reference_id": "34d9cfd0-726a-40ef-be00-7f010e9b1a28",
        "virtual_account": null,
        "over_the_counter": null,
        "billing_information": {
            "city": null,
            "country": "",
            "postal_code": null,
            "street_line1": null,
            "street_line2": null,
            "province_state": null
        },
        "direct_bank_transfer": null
    },
    "event": "payment_method.failed",
    "created": "2023-08-10T10:48:50.5388319Z",
    "business_id": "6396e6d48c59c18ca0e55218"
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment_method.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Method object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.

Callback Payload

Example: Payment Succeeded Callback Payload

{
    "event": "payment.succeeded",
    "data": {
        "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
        "amount": 1000,
        "status": "SUCCEEDED",
        "country": "PH",
        "created": "2022-08-12T13:30:40.9209Z",
        "updated": "2022-08-12T13:30:58.729373Z",
        "currency": "PHP",
        "metadata": {
            "sku": "ABCDEFGH"
        },
        "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
        "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
        "payment_method": {
            "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
            "card": null,
            "type": "DIRECT_DEBIT",
            "status": "ACTIVE",
            "created": "2022-08-12T13:30:26.579048Z",
            "ewallet": null,
            "qr_code": null,
            "updated": "2022-08-12T13:30:40.221525Z",
            "metadata": null,
            "description": null,
            "reusability": "MULTIPLE_USE",
            "direct_debit": {
                "type": "BANK_ACCOUNT",
                "debit_card": null,
                "bank_account": {
                    "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                    "masked_bank_account_number": "XXXXXX1234"
                },
                "channel_code": "BPI",
                "channel_properties": {
                    "failure_return_url": "https://your-redirect-website.com/failure",
                    "success_return_url": "https://your-redirect-website.com/success"
                }
            },
            "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
            "virtual_account": null,
            "over_the_counter": null,
            "direct_bank_transfer": null
        },
        "description": null,
        "failure_code": null,
        "payment_detail": null,
        "channel_properties": null,
        "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
    },
    "created": "2022-08-12T13:30:58.986Z",
    "business_id": "5f27a14a9bf05c73dd040bc8",
    "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.succeeded
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status SUCCEEDED

This callback is sent when a pending EWALLET, DIRECT_DEBIT, or CARD has failed.

Note: Make sure that you ONLY have a callback URL registered in the Payment Request section in your Dashboard settings for payments. To prevent duplicate callbacks, DO NOT fill out product-specific sections.

Callback Payload

Example: Payment Failed Callback Payload

{
  "event": "payment.failed",
  "data": {
      "id": "ddpy-3cd658ae-25b9-4659-aa36-596ae41a809f",
      "amount": 1000,
      "status": "FAILED",
      "country": "PH",
      "created": "2022-08-12T13:30:40.9209Z",
      "updated": "2022-08-12T13:30:58.729373Z",
      "currency": "PHP",
      "metadata": {
          "sku": "ABCDEFGH"
      },
      "customer_id": "c832697e-a62d-46fa-a383-24930b155e81",
      "reference_id": "25cfd0f9-baee-44ca-9a12-6debe03f3c22",
      "payment_method": {
          "id": "pm-951b1ad9-1fbb-4724-a744-8956ab6ed17f",
          "card": null,
          "type": "DIRECT_DEBIT",
          "status": "ACTIVE",
          "created": "2022-08-12T13:30:26.579048Z",
          "ewallet": null,
          "qr_code": null,
          "updated": "2022-08-12T13:30:40.221525Z",
          "metadata": null,
          "description": null,
          "reusability": "MULTIPLE_USE",
          "direct_debit": {
              "type": "BANK_ACCOUNT",
              "debit_card": null,
              "bank_account": {
                  "bank_account_hash": "b4dfa99c9b60c77f2e3962b73c098945",
                  "masked_bank_account_number": "XXXXXX1234"
              },
              "channel_code": "BPI",
              "channel_properties": {
                  "failure_return_url": "https://your-redirect-website.com/failure",
                  "success_return_url": "https://your-redirect-website.com/success"
              }
          },
          "reference_id": "620b9df4-fe69-4bfd-b9d4-5cba6861db8a",
          "virtual_account": null,
          "over_the_counter": null,
          "direct_bank_transfer": null
      },
      "description": null,
      "failure_code": "INSUFFICIENT_BALANCE",
      "payment_detail": null,
      "channel_properties": null,
      "payment_request_id": "pr-5b26cae1-545b-49e9-855e-f85128f3e705"
  },
  "created": "2022-08-12T13:30:58.986Z",
  "business_id": "5f27a14a9bf05c73dd040bc8",
  "api_version": null
}

Header Parameters

Header Parameter Type Description
x-callback-token
required
string Your Xendit unique callback token to verify the origin of the callback

webhook-id
required
string A unique identifier of every webhook to help you to handle double callback by implementing idempotency. When you receive the same webhook-id twice, treat the subsequent request as duplicate and reject the webhook accordingly to prevent double webhook

Body Parameter Type Description
event
required
string Identifies the event that triggered a notification to the merchant - payment.failed
business_id
required
string Business ID of the merchant
created
required
string ISO 8601 Timestamp for callback notification creation. Timezone UTC+0.
data
optional
object Payment Object with status FAILED. See the Failure Code table below to see the possible values of failure_code.
Failure Code Description
ACCOUNT_ACCESS_BLOCKED
End customer bank account has been blocked, end user should contact the bank for resolution.
ACCOUNT_NOT_ACTIVATED
End-customer's account is not activated for payments.
CHANNEL_UNAVAILABLE
The partner channel cannot be reached or currently having a downtime
CUSTOMER_UNREACHABLE
The end-user's device cannot be reached at this moment by the partner channel
DUPLICATE_ERROR
There's an existing record of linking the same underlying account for the provided customer_id OR Virtual Account Number/Payment Code already exists
INSUFFICIENT_BALANCE
Source of funds has insufficient balance to complete the transaction
INVALID_MERCHANT_CREDENTIALS
Merchant credentials met with an error with the partner channel
INVALID_PAYMENT_METHOD
The provided payment method id has already expired or is inactive
MAX_ACCOUNT_LINKING
Partner channel blocked the linking because the underlying account has been linked to the maximum number allowed by the channel.
MAX_AMOUNT_LIMIT_ERROR
The transaction amount exceeds the partner channel's set limits
MAX_OTP_ATTEMPTS_ERROR
The maximum incorrect attempts allowed by the channel has been reached.
PARTNER_CHANNEL_ERROR
Error received from partner channel but no reasons provided
SERVER_ERROR
An unexpected error occured. Our team has been notified and will troubleshoot the issue.
PAYMENT_METHOD_ALREADY_EXISTS
An active Payment Method with the same customer_id, channel_code for that merchant already exists.
PAYMENT_EXPIRED
If you are using Xendit-hosted OTP page, end-user needs to input their OTP within 15 minutes or else the payment will be expired. You may need to create a new payment.
PAYMENT_STATUS_FAILED
Payment has failed with no further information from channel. You may need to check before retrying. Recommended to wait ~30 minutes before retrying unless given further instruction.