Payment Intent Creation
API Request Parameters
Note
- All
JSON
fields must be stringified before submission - Nested objects must be serialized to
JSON
string format JSON
fields must not contain unescaped special characters- Arrays in
JSON
should be properly formatted - Example of
JSON
string field:
{
"object": "{\"obj-key1\":\"v1\",\"obj-key2\":\"v2\"}",
"complex": "{\"k1\":\"v1\",\"array\":\"[{\\\"obj-key3\\\":\\\"v3\\\",\\\"obj-key4\\\":\\\"v4\\\"}]\"}"
}
2
3
4
Parameter | Type | Length | Required | Signed | Description |
---|---|---|---|---|---|
billingInformation | String | / | Yes | Yes | Billing information in JSON string format. See TransactionAddress |
lpmsInfo | String | / | Conditional | Yes | Local payment method information in JSON string format. See LpmsInfo |
merchantCustId | String | 50 | Conditional | Yes | Unique customer identifier in merchant system. |
merchantNo | String | 20 | Yes | Yes | Merchant number assigned by |
merchantTxnId | String | 64 | Yes | Yes | Unique transaction identifier for each customer payment. Must be unique for each transaction request. |
merchantTxnOriginalId | String | 128 | No | Yes | Master transaction ID generated by merchant. IDs can be duplicate but only one transaction with the same ID can succeed |
merchantTxnTime | String | / | No | Yes | Transaction timestamp (Format: |
merchantTxnTimeZone | String | 64 | No | Yes | Transaction timezone |
mpiInfo | String | / | Conditional | Yes | 3DS verification result information in JSON string format. See MpiInfo |
orderAmount | String | 19 | Yes | Yes | Order amount in units of currency with max 2 decimal places |
orderCurrency | String | 8 | Yes | Yes | Order currency code. See ISO 4217 |
originTransactionId | String | 20 | Conditional | Yes | Original transaction ID from Onerway |
osType | String | 16 | Conditional | Yes | Operating system type. See OsTypeEnum |
paymentMode | String | 16 | No | Yes | Payment mode. Default is |
productType | String | 16 | Yes | Yes | See ProductTypeEnum |
risk3dsStrategy | String | 16 | Conditional | Yes | 3DS risk control strategy. See Risk3dsStrategyEnum |
shippingInformation | String | / | Yes | Yes | Shipping information in JSON string format. See TransactionAddress |
sign | String | / | Yes | No | Digital signature string for request verification. Please refer to Signature for signature generation method. |
subProductType | String | 16 | Yes | Yes | See SubProductTypeEnum |
subscription | String | / | Conditional | Yes | Subscription information in JSON string format. See Subscription. |
txnOrderMsg | String | / | Yes | Yes | Transaction business information in JSON string format. See TxnOrderMsg |
txnType | String | 16 | Yes | Yes | Transaction type. See TxnTypeEnum |
TransactionAddress
Name | Type | Length | Required | Signature | Description |
---|---|---|---|---|---|
firstName | String | 64 | No | No | First name |
lastName | String | 64 | No | No | Last name |
jpFirstName | String | 64 | No | No | (Japanese Katakana) First name |
jpLastName | String | 64 | No | No | (Japanese Katakana) Last name |
phone | String | 32 | No | No | Phone number |
String | 256 | Yes | No | Email address | |
postalCode | String | 32 | No | No | Postal code |
address | String | 256 | No | No | Address |
country | String | 64 | Yes | No | |
province | String | 64 | Conditional | No | |
city | String | 64 | No | No | City |
street | String | 64 | No | No | Street |
number | String | 64 | No | No | House/Building number |
identityNumber | String | 64 | No | No | ID number |
birthDate | String | 64 | No | No | Birth date, format is |
MpiInfo
Name | Type | Length | Required | Signature | Description |
---|---|---|---|---|---|
eci | String | 2 | Yes | No | Electronic Commerce Indicator (ECI). |
cavv | String | 128 | Yes | No | Cardholder Authentication Verification Value (CAVV). |
xid | String | 128 | No | No | 3D-Secure v1 transaction identifier. |
dsTransID | String | 128 | No | No | 3D-Secure v2 transaction identifier. |
TxnOrderMsg
Name | Type | Length | Required | Signature | Description |
---|---|---|---|---|---|
returnUrl | String | 256 | Yes | No | Synchronous return address. After the customer completes payment, the |
products | String | 1024 | Yes | No | |
transactionIp | String | 64 | Conditional | No | Cardholder transaction |
appId | String | 20 | Yes | No | Store |
javaEnabled | Boolean | / | Conditional | No | Whether the cardholder's browser has |
colorDepth | String | 64 | Conditional | No | Cardholder screen color depth, retrieved via: |
screenHeight | String | 64 | Conditional | No | Cardholder's screen resolution, retrieved via: |
screenWidth | String | 64 | Conditional | No | Cardholder's screen resolution, retrieved via: |
timeZoneOffset | String | 64 | Conditional | No | Cardholder browser's time zone, retrieved via: |
accept | String | 2048 | Conditional | No | Cardholder browser's |
userAgent | String | 2048 | Conditional | No | Cardholder's browser type, retrieved via: |
contentLength | String | 64 | Conditional | No | Content length of the cardholder's browser content beyond the headers |
language | String | 64 | Conditional | No | Cardholder's browser language, retrieved via: |
periodValue | String | / | Conditional | No | Installment payment period. |
notifyUrl | String | 256 | Yes | No |
Products
Name | Type | Length | Required | Description |
---|---|---|---|---|
name | String | 256 | Yes | Product name |
price | String | 1024 | Yes | Product unit price |
num | String | 20 | Yes | Product quantity |
desc | String | 1024 | No | Product description |
currency | String | 256 | Yes | Currency code following ISO 4217 standard |
type | String | 256 | No | Product classification. See StoreProductTypeEnum |
products
must be in JSON
string format
Examples:
If type is discount, the discount amount should be passed as a negative number\"[{\\\"name\\\":\\\"Pro1\\\",\\\"price\\\":\\\"50.00\\\",\\\"num\\\":\\\"2\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"Pro2\\\",\\\"price\\\":\\\"100\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\"}]\"
\"[{\\\"name\\\":\\\"Pro1\\\",\\\"price\\\":\\\"50.00\\\",\\\"num\\\":\\\"2\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"Pro2\\\",\\\"price\\\":\\\"100\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"discount\\\",\\\"price\\\":\\\"-10\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\",\\\"type\\\":\\\"discount\\\"}]\"
\"[{\\\"name\\\":\\\"Pro1\\\",\\\"price\\\":\\\"50.00\\\",\\\"num\\\":\\\"2\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"Pro2\\\",\\\"price\\\":\\\"100\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"shipping fee\\\",\\\"price\\\":\\\"10\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\",\\\"type\\\":\\\"shipping_fee\\\"}]\"
\"[{\\\"name\\\":\\\"Pro1\\\",\\\"price\\\":\\\"50.00\\\",\\\"num\\\":\\\"2\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"Pro2\\\",\\\"price\\\":\\\"100\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\"},{\\\"name\\\":\\\"shipping fee\\\",\\\"price\\\":\\\"10\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\",\\\"type\\\":\\\"shipping_fee\\\"},{\\\"name\\\":\\\"discount\\\",\\\"price\\\":\\\"-10\\\",\\\"num\\\":\\\"1\\\",\\\"currency\\\":\\\"USD\\\",\\\"type\\\":\\\"discount\\\"}]\"
Note that price * num (product amount) + price * num (discount amount) - price * num (shipping fee) = orderAmount (order transaction amount)
Response
Name | Type | Description |
---|---|---|
respCode | String | Response code from |
respMsg | String | Response message from |
data | Object |
data
Name | Type | Description |
---|---|---|
transactionId | String | Transaction order number created by |
merchantTxnId | String | Customer's payment order number for each payment |
merchantNo | String | Merchant number. When a merchant registers, |
responseTime | String | Interface response time, format: |
txnTime | String | Transaction completion time, format: |
orderAmount | String | Order amount |
orderCurrency | String | |
txnAmount | String | Order amount after conversion to settlement currency. Null when transaction is not completed |
txnCurrency | String | |
txnTimeZone | String | Transaction time zone |
status | String | Transaction processing result. Refer to TxnStatusEnum |
reason | String | Reason for transaction failure |
redirectUrl | String | SDK initialization URL, used to initialize the SDK component on the merchant's website |
sign | String | |
contractId | String | Subscription contract number: Identifies which subscription it is, an important parameter for completing subscription repurchase. Usually stored in pairs with |
tokenId | String | Subscription |
eci | String | Liability shift, parameter required for |
periodValue | String | Installment payment number of periods |
codeForm | String | Form of code for alternative payment methods. Refer to CodeFormEnum |
presentContext | String | Additional context information for SDK display |
actionType | String | Type of action to be performed. Refer to ActionTypeEnum |
subscriptionManageUrl | String | Subscription management URL, buyers can view subscription order information through this address |
SDK Integration Process
The SDK integration process consists of three main phases as illustrated below:
1. Payment Intent Creation
In this phase:
- Client submits order information to the merchant server
- Merchant server sends a payment request to Onerway with transaction details including
merchantNo
,orderAmount
, andtxnOrderMsg
parameters txnOrderMsg
must containreturnUrl
(for synchronous notification) andnotifyUrl
(for webhook notification)- Onerway creates a transaction record and returns a
transactionId
andredirectUrl
- The initial transaction status is
Unfinished
(U)
2. SDK Payment Process
In this phase:
- Client loads the Onerway SDK JavaScript library
- Client initializes the SDK with the
transactionId
andredirectUrl
received from the merchant server - SDK renders the payment interface embedded in the merchant's website/app
- Customer enters payment information in the SDK interface
- If standard payment is used, the process completes directly with
status
=S
(Success) - If
3D Secure
(3DS) verification is required (for enhanced security with credit card payments):- Onerway Payment System returns
status
=R
and aredirectUrl
containing the 3DS verification link - Important: The merchant must implement their own logic to handle the redirect to the 3DS verification page
- After completing 3DS verification, the customer is returned to the merchant site with the payment result
- Onerway Payment System returns
3. Payment Result Notification
In this phase:
Synchronized notification:
- SDK receives the transaction result and triggers the
onPaymentCompleted
oronError
callback function - The callback provides essential result parameters including
transactionId
,status
- User is redirected back to merchant's site via the
returnUrl
specified intxnOrderMsg
- SDK receives the transaction result and triggers the
Asynchronous notification (webhook):
- Simultaneously, Onerway sends detailed payment result data to the
notifyUrl
via HTTPPOST
- The webhook contains complete transaction information including
transactionId
,status
,paymentMethod
, andsignature
for verification - Webhook data is more comprehensive than the synchronized notification and should be used as the source of truth
- Simultaneously, Onerway sends detailed payment result data to the
Webhook acknowledgment:
- Merchant server must respond with
transactionId
to acknowledge receipt of the webhook - If no successful response is received, Onerway will retry sending the webhook up to
3
times at 30-minute intervals - Implement idempotent processing to handle potential duplicate notifications
- Merchant server must respond with
Payment Completion Examples
{
"respCode": "20000",
"respMsg": "Success",
"data": {
"transactionId": "1919257784533516288",
"responseTime": "2025-05-05 13:08:39",
"txnTime": "2025-05-05 13:08:08",
"txnTimeZone": "+08:00",
"orderAmount": "45.00",
"orderCurrency": "USD",
"txnAmount": null,
"txnCurrency": null,
"status": "R",
"redirectUrl": "https://sandbox-gw-dmz.onerway.com/3dsSecure/direct/RDT_3DS_DDC_8002091919257909569650689", // 3DS verification page
"contractId": null,
"tokenId": null,
"eci": null,
"periodValue": null,
"codeForm": null,
"presentContext": null,
"actionType": "RedirectURL",
"subscriptionManageUrl": null,
"sign": null
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
"notifyType": "TXN",
"transactionId": "1919257939122978816",
"txnType": "SALE",
"merchantNo": "800209",
"merchantTxnId": "1746421724000",
"responseTime": "2025-05-05 13:11:29",
"txnTime": "2025-05-05 13:11:12",
"txnTimeZone": "+08:00",
"orderAmount": "45.00",
"orderCurrency": "USD",
"status": "S",
"eci": "05",
"cardBinCountry": "US",
"reason": "{\"respCode\":\"20000\",\"respMsg\":\"Success\"}",
"sign": "35eb3ed3790367e464a15a99eff3ed163bd1c96a043018d605de3a4023ddcd12",
"paymentMethod": "VISA",
"channelRequestId": "8002091919258558784995328"
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Important Notes
- Always rely on webhook notifications as the definitive source for transaction status
- SDK callbacks are primarily for enhancing user experience but should not be the sole basis for order processing
- Multiple webhook notifications may be received for a single transaction; deduplication based on transaction ID is recommended
- Transaction status
S
indicates success,F
indicates failure; refer to TxnStatusEnum for other status codes - The SDK provides callbacks for various payment stages, which helps in creating a responsive user experience
API Usage Examples
{
"billingInformation": "{\"address\":\"824 Blind Lane\",\"city\":\"North Ameliaside\",\"country\":\"US\",\"email\":\"Emmanuel26@hotmail.com\",\"firstName\":\"Kiel\",\"identityNumber\":\"14364522468\",\"lastName\":\"Marvin\",\"phone\":\"18057477053\",\"postalCode\":\"12308-1270\",\"province\":\"CO\"}",
"merchantCustId": "CustId-I5PE-DN25",
"merchantNo": "800209",
"merchantTxnId": "195307a0-f5de-4e9d-ad3d-faf1c6ac9d10",
"merchantTxnTime": "2025-05-05 13:14:23",
"orderAmount": "3",
"orderCurrency": "USD",
"productType": "CARD",
"shippingInformation": "{\"address\":\"259 Wilton Street\",\"city\":\"Denaton\",\"country\":\"US\",\"email\":\"Olen94@yahoo.com\",\"firstName\":\"Matteo\",\"identityNumber\":\"20373861755\",\"lastName\":\"Berge\",\"phone\":\"15690923060\",\"postalCode\":\"29150-8270\",\"province\":\"CO\"}",
"sign": "698917d17492a3205ccff0d030d84cc6fef9ab903edf50998560cc374f3b419c",
"subProductType": "DIRECT",
"txnOrderMsg": "{\"accept\":\"*/*\",\"appId\":\"1727880846378401792\",\"colorDepth\":\"24\",\"contentLength\":\"16384\",\"javaEnabled\":true,\"language\":\"en-US\",\"products\":\"[{\\\"currency\\\":\\\"USD\\\",\\\"name\\\":\\\"starfruit\\\",\\\"num\\\":\\\"49\\\",\\\"price\\\":\\\"245.89\\\",\\\"type\\\":\\\"aliqua\\\"},{\\\"currency\\\":\\\"USD\\\",\\\"name\\\":\\\"blueberry\\\",\\\"num\\\":\\\"89\\\",\\\"price\\\":\\\"160.09\\\",\\\"type\\\":\\\"ut aliqua\\\"},{\\\"currency\\\":\\\"USD\\\",\\\"name\\\":\\\"papaya\\\",\\\"num\\\":\\\"47\\\",\\\"price\\\":\\\"719.60\\\",\\\"type\\\":\\\"in consectetur minim\\\"}]\",\"returnUrl\":\"https://docs.onerway.com/\",\"notifyUrl\":\"https://docs.onerway.com/apis\",\"screenHeight\":\"780\",\"screenWidth\":\"320\",\"timeZoneOffset\":\"-660\",\"transactionIp\":\"158.63.117.41\",\"userAgent\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36\"}",
"txnType": "SALE"
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"respCode": "20000",
"respMsg": "Success",
"data": {
"transactionId": "1919259367895859200", // transactionId for SDK initialization
"responseTime": "2025-05-05 13:14:26",
"txnTime": null,
"txnTimeZone": "+08:00",
"orderAmount": "3.00",
"orderCurrency": "USD",
"txnAmount": null,
"txnCurrency": null,
"status": "U",
"redirectUrl": "https://sandbox-checkout-sdk.onerway.com", // URL for SDK initialization
"contractId": null,
"tokenId": null,
"eci": null,
"periodValue": null,
"codeForm": null,
"presentContext": null,
"actionType": null,
"subscriptionManageUrl": null,
"sign": "119a387fb282fe9d8eb82f86a4287e582bc833a71bdd42767be665be031964d8"
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
SDK Initialization
After receiving the transactionId
and redirectUrl
from the Payment Intent Creation API, initialize the SDK with the following steps:
// Import the Onerway SDK script
const script = document.createElement('script');
script.src = 'https://checkout-sdk.onerway.com/v3/';
document.body.appendChild(script);
// Create SDK container
const container = document.createElement('div');
container.id = 'onerway_checkout';
document.body.appendChild(container);
// Initialize SDK once loaded
script.onload = function() {
const pacypay = new Pacypay(transactionId, {
container: 'onerway_checkout', // DOM element ID to render the SDK
locale: 'en', // Checkout language, see Localization section below
environment: 'sandbox', // 'sandbox' or 'production'
mode: 'CARD', // Payment method: 'CARD', 'ApplePay', or 'GooglePay'
redirectUrl: 'REDIRECT_URL_FROM_API', // Obtained from server-side API
config: {
subProductType: 'DIRECT', // Must match the subProductType in Payment Intent Creation API
// Additional configuration options detailed below
},
onPaymentCompleted: function(result) {
console.log('Payment result:', result);
// Handle payment result and 3ds verification
},
onError: function(error) {
console.log('Payment failed:', error);
// Handle payment errors
}
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
SDK Features and Customization
The Onerway SDK offers comprehensive customization options to match your brand identity and user experience requirements:
Configuration Options
config: {
// Required: Must match the subProductType in Payment Intent Creation API
subProductType: 'DIRECT', // 'DIRECT' for direct/subscription payments; 'TOKEN' for tokenized payments
// Theme Settings
checkoutTheme: 'light', // 'light' or 'dark'
// Custom CSS URL (overrides checkoutTheme when provided)
customCssURL: 'https://your-domain.com/custom-styles.css',
// UI Control Options
showPayButton: true, // Whether to display the default payment button
buttonSeparation: false, // For 'TOKEN': whether to separate card binding and payment steps
displayBillingInformation: true, // Whether to display billing information
hideTokenList: false, // For 'TOKEN': whether to hide previously bound cards
// Additional configuration options...
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Theme Customization
Customize the SDK appearance through theme variables:
config: {
// Other configuration options...
variables: {
colorBackground: '#ffffff', // Theme background color
colorPrimary: '#4CAF50', // Primary theme color for input highlights, cursor, etc.
colorText: '#333333', // Text color
colorDanger: '#ff0000', // Error message color
borderRadius: '8px', // Input field border radius
fontSizeBase: '16px', // Base font size (scales other elements proportionally)
fontFamily: 'Arial, sans-serif' // Font family
}
}
2
3
4
5
6
7
8
9
10
11
12
For fine-grained control over individual elements, use the styles
object to apply custom CSS:
config: {
// Other configuration options...
styles: {
// Payment method container styles
'.pacypay-checkout__payment-method': { /* container styles */ },
// Header section
'.pacypay-checkout_payment-method_header': { /* header styles */ },
'.pacypay-checkout_payment-methodheader_title': { /* title styles */ },
'.pacypay-checkout_payment-methodimage_wrapper': { /* image container styles */ },
'.pacypay-checkout_payment-method_brands': { /* card brands container styles */ },
'.pacypay-checkout_payment-method_image': { /* header image styles */ },
'.pacypay-checkout_payment-method_brand': { /* card brand image styles */ },
'.pacypay-checkout_payment-method_name': { /* header title styles */ },
// Form content
'.pacypay-checkout_payment-method_details': { /* form container styles */ },
'.pacypay-checkout__field-wrapper': { /* form field container styles */ },
'.pacypay-checkout__field': { /* form field styles */ },
// Specific form fields
'.pacypay-checkout__field--cardNumber': { /* card number field styles */ },
'.pacypay-checkout__field--expire': { /* expiry date field styles */ },
'.pacypay-checkout__field--cvv': { /* CVV field styles */ },
'.pacypay-checkout__field--lastName': { /* name field styles */ },
// Form labels and inputs
'.pacypay-checkout__label-text': { /* field label styles */ },
'.pacypay-checkout__label-text--require': { /* required field indicator styles */ },
'.pacypay-checkout__input': { /* input field styles */ },
'.pacypay-checkout__error-text': { /* error message styles */ },
// Buttons
'.pacypay-checkout__button': { /* general button styles */ },
'.pacypay-checkout__button--pay': { /* pay button styles */ },
'.pacypay-checkout_button_text': { /* button text styles */ },
// Loading indicators
'.pacypay-checkout__loading': { /* loading container styles */ },
'.pacypay-checkout__spinner': { /* loading animation styles */ }
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
Note: If you need to completely customize all styles, you can define only the styles
object and omit checkoutTheme
, customCssURL
, and variables
.
Custom Payment Button
To implement a custom payment button, set showPayButton: false
and invoke the submit()
method:
// SDK configuration
const pacypay = new Pacypay(transactionId, {
// Other configuration options...
container: 'onerway_checkout',
config: {
showPayButton: false,
displayBillingInformation: false
}
});
// Custom button event handler
document.getElementById('custom-payment-button').addEventListener('click', function() {
pacypay.submit({
billingInformation: {
firstName: "John",
lastName: "Doe",
phone: "1234567890",
email: "john.doe@example.com",
postalCode: "10001",
address: "123 Main St",
country: "US",
province: "NY",
city: "New York",
identityNumber: "123456789"
}
});
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Localization
The SDK supports multiple languages for the checkout interface. Specify the preferred language with the locale
parameter:
const pacypay = new Pacypay(transactionId, {
// Other configuration options...
locale: 'en', // Available options: en, zh-cn, ar, de, es, fi, fr, it, ja, ko, nl, no, pl, pt, ru, sv, th, zh-tw
});
2
3
4
Complete Integration Example
// Step 1: Import the SDK script
const script = document.createElement('script');
script.src = 'https://checkout-sdk.onerway.com/v3/';
document.body.appendChild(script);
// Step 2: Create SDK container
const container = document.createElement('div');
container.id = 'onerway_checkout';
document.body.appendChild(container);
script.onload = function() {
// Step 3: Initialize the SDK
const transactionId = 'TRANSACTION_ID_FROM_API';
const redirectUrl = 'REDIRECT_URL_FROM_API';
const pacypay = new Pacypay(transactionId, {
locale: 'en',
environment: 'sandbox',
mode: 'CARD',
container: 'onerway_checkout',
redirectUrl: redirectUrl,
config: {
subProductType: 'DIRECT', // Must match the value in Payment Intent Creation API
checkoutTheme: 'light',
variables: {
colorPrimary: '#3f51b5',
borderRadius: '4px'
}
},
onPaymentCompleted: function(res) {
// Handle payment completion
const txnInfo = res.data;
const respCode = res.respCode;
const respMsg = res.respMsg;
if(respCode === '20000') { // Success response
switch(txnInfo.status) {
case 'S': // Payment successful
console.log('Transaction successful');
// Note: Final payment status should be confirmed via webhook
break;
case 'R': // 3DS verification required
// Important: Redirect to 3DS verification page
window.location.href = txnInfo.redirectUrl;
break;
default:
console.log('Transaction status:', txnInfo.status);
}
} else {
console.error('Transaction failed:', respMsg);
}
},
onError: function(err) {
console.error('SDK error:', err);
}
});
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
Implementation Best Practices
- Ensure the
subProductType
value matches exactly what was used in the Payment Intent Creation API - Always consider the webhook notification as the source of truth for transaction status
- Implement proper redirect handling for 3DS verification flows
- Process webhook notifications idempotently to handle potential duplicate notifications
- Test thoroughly in sandbox environment before moving to production
- For security reasons, validate all transaction responses on your server side
- Implement proper error handling to provide a seamless user experience