Click2Pay
This guide is providing guidance on who to implement click2Pay on merchant payment page.
- Customer landing on merchant checkout page
- Merchant to send payment token API
- Merchant receive payment token response
- Merchant send Payment Option Detail API
- Merchant receive Payment Option Detail response with the
CaptureContextvalue that is required for front-end JS - Populate click2pay event() & button
- Customer proceed Payment with click2Pay
- click2pay drop-in UI to display
- Customer key in identity & card detail on click2pay drop-in UI and submit payment
- Click2pay service will return
token - Merchant send do payment API with
token - Merchant receive do payment response
- Redirect Customer to perform 3ds authentication
- Merchant receive payment result upon payment completed
Pre requisite
On the merchant payment page, it is required
- add Cybersource js lib
- add
<div>used to populate click2pay button
<html>
<body><div id="payment-container"></div> <!--to show click to pay button-->
</body>
<script src="https://testup.cybersource.com/uc/v1/assets/0.28.2/SecureAcceptance.js"></script>
<!--Cybersource js
prod url : https://up.cybersource.com/uc/v1/assets/0.28.3/SecureAcceptance.js
-->
</html>Payment Token Request
Request Payment Token API with CLICK2PAY payment channel code
{
"merchantID": "JT01",
"invoiceNo": "1523953661",
"description": "item 1",
"amount": 1000.00,
"currencyCode": "SGD",
"paymentChannel": ["CLICK2PAY"]
}Request CaptureContext via Payment Option Detail API
CaptureContext via Payment Option Detail APITo specific request for click2pay, required to send
- categoryCode :
DPAY - groupCode :
CWALLET - in HTTP header required to add merchant website domain.
- This is required for click2pay service to whitelist when merchant website is populate the drop-in UI
- The website domain provided MUST be same as the provided website when onboard with 2c2p
X-Merchant-Domain : <merchant-domain>
url --location 'https://sandbox-pgw.2c2p.com/payment/4.3/PaymentOptionDetails' \
--header 'X-Merchant-Domain: https://merhcantABC.com' \
--header 'Content-Type: application/json' \
--data '{"paymentToken": "kSAops9Zwhos8hSTSeLTUTndJJj51v8PCyu4uHoefMlPOgG39WOcgWgVfPAcQ9NRQHQBWvXl9q6OCvZBWzDoOBVQ24dKUIZ5slcL1Oo5TpQ=", "categoryCode" : "DPAY", "groupCode": "CWALLET"}'Receive CaptureContext data from Channels[].payment.token
{
"totalChannel": 1,
"name": null,
"categoryCode": "DPAY",
"groupCode": "CWALLET",
"iconUrl": "https://d27uu9vmlo4gwh.cloudfront.net/images/v4/images/icon/wallet.png",
"channels": [
{
"sequenceNo": 7,
"name": "Click2Pay",
"bankShortName": null,
"currencyCodes": null,
"iconUrl": "https://d27uu9vmlo4gwh.cloudfront.net/images/v4/images/icon/click2pay.png",
"logoUrl": "https://d27uu9vmlo4gwh.cloudfront.net/images/v4/images/logo/click2pay.png",
"payment": {
"code": {
"channelCode": "CLICK2PAY"
},
"input": {
"name": "O",
"email": "O",
"customerNote": "I"
},
"validation": {
"name": "^(?!\\s*$)[-a-zA-Z' ''.']{1,}$",
"email": "^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$",
"customerNote": "(.*?)"
},
"info": {
"customData": [],
"provider": {
"id": "",
"channels": [
"MA",
"VI",
"UP",
"MD"
],
"merchantDetails": {
"id": "458458000000000",
"name": "SCCS",
"countryCode": "MY"
},
"transactionDetails": {
"amount": 10,
"currencyCode": "MYR",
"invoiceNo": "270226105906",
"description": "V4 Test"
},
"termsConsent": false
},
"termsConsent": false,
"token": "eyJraWQiOiJ3ZiIsImFsZyI6IlJTMjU2In0.eyJmbHgiOnsicGF0aCI6Ii9mbGV4L3YyL3Rva2VucyIsImRhdGEiOiJ4VU45YmY3bEh2QU0yRElWZWlCZFZHMTN6UVJoWlUwVnlQNVVRQlA4cUN4cHc1UElGNFF4UmZFY1hmWHM1V1JvdDFON1BrWnJlaTlJb3hQbVM5RHZxdnRBV1Roenl1LVV3dlJMeGh0bU5ZMUx0SmZ0S2ZfbTl1bEtOblVNa1NjRk0temVwd2o2RC00Ni1RWm11RldONUVaOWlydFJ2Y1d3NzQwS0hhRW92THBvS2RDMXhzZ1N5UWZUNG04ZVVpc2VJLWs3UTdCR1hqTjFycDdZQS1taUdMOUxqSDZsZzg0OGY1UFoiLCJvcmlnaW4iOiJodHRwczovL2ZsZXguY3liZXJzb3VyY2UuY29tIiwidHJhbnNpZW50VG9rZW5PcGVyYXRpb25zIjpbeyJzdWIiOiIyYzJwX2MycF9nbG9iYWwwMDEiLCJhdWQiOiIyYzJwX3BvcnRmb2xpbyIsImtpZCI6IjIwMjQxMjE4LTJjMnAtcHVibGljIiwidHlwZSI6IlNUT1JFIn1dLCJ0b2tlbnNVcmwiOiJodHRwczovL2ZsZXguY3liZXJzb3VyY2UuY29tL2ZsZXgvdjIvdG9rZW5zIiwiandrIjp7Imt0eSI6IlJTQSIsImUiOiJBUUFCIiwidXNlIjoiZW5jIiwibiI6ImwyV0xfYmRQdzJMekJ3RjYxZjgwZHJTdHp4SnJENUhtWkNHN0dRTFQ4VG5zTXN0bldhMmRVYTBPQWM2M0MxNUJlU0VPLWY1YTNuY0FsOUhMX3QyWGVNUFdmX2ZLSDhRMWdwRHB1OVM1SmNQMC1FNzI4WGJoT2FLaEVMa25UZUVjdVFiNWhhdUppbS1wMV9Sd2RVNlQxX09rSHJ5NjFPMmw2c1RYSUJIZVp6LWJWRTJacmtzUjdWNjhJaG5uaHViRnNkdEVEc182d1UtcTdHUjBlbXNUUDZldFNzMU5oYkFwUVpVdTE2SGJfaU4zX09idl9ObF93cmNmZVVfLUEwZGVoaFY1WHdST2pxODNjNHNkbkVGY1RiMGpwYUZzdFZYUzhtc1plZHc4V0dnMk5IMjRxSDV2ZUZDYXIwUW1KVC16T1dGZ0dqdS03RTB2dXl4VDBZdTZ4USIsImtpZCI6IjAzVzQxTG4wZWJJaE45NnZuRUxWNWQ3OGt1dWhFYmJmIn19LCJjdHgiOlt7ImRhdGEiOnsiYWxsb3dlZFBheW1lbnRUeXBlcyI6WyJDTElDS1RPUEFZIiwiUEFORU5UUlkiXSwib3JkZXJJbmZvcm1hdGlvbiI6eyJhbW91bnREZXRhaWxzIjp7InRvdGFsQW1vdW50IjoiMTAuMDAiLCJjdXJyZW5jeSI6Ik1ZUiJ9fSwiY2FwdHVyZU1hbmRhdGUiOnsic2hvd0NvbmZpcm1hdGlvblN0ZXAiOnRydWUsImJpbGxpbmdUeXBlIjoiTk9ORSIsInJlcXVlc3RFbWFpbCI6dHJ1ZSwicmVxdWVzdFBob25lIjpmYWxzZSwicmVxdWVzdFNoaXBwaW5nIjpmYWxzZSwic2hpcFRvQ291bnRyaWVzIjpbIk1ZIl0sInNob3dBY2NlcHRlZE5ldHdvcmtJY29ucyI6ZmFsc2V9LCJwYXltZW50Q29uZmlndXJhdGlvbnMiOnsiU1JDVklTQSI6eyJvcmlnaW4iOiJodHRwczovL2Fzc2V0cy5zZWN1cmUuY2hlY2tvdXQudmlzYS5jb20iLCJwYXRoIjoiL2NoZWNrb3V0LXdpZGdldC9yZXNvdXJjZXMvanMvc3JjLWktYWRhcHRlci92aXNhU2RrLmpzP3YyIiwicGFuRW5jcnlwdGlvbktleSI6eyJraWQiOiJaSFBRQlowVko4VTJKQlZRTjVaVzE0d2tPaXNOektkT1AtQjMxQXZLS0FYNENMeldFIiwiZSI6IkFRQUIiLCJuIjoia1B1andWSmpldklfb2Vad1pvQTJXanQ5NERGY012UkNhYjhpUmlFR3JHZktXdE5Dd1FZa3lseXVSb0I2MTVjWW0yQlZidm9LSDhZeXYwYUMzZHdhaDZVbU9kSnN6bUwwcFZfY2J4X3RYeldnWWczc1lOc3Awc0J4VUZjUTFBNkRWYnlPeHhKYm1ud2xIR0U1Zmt1ekpyLXFxdWwzUnN3c0NHLXZQcmhfLS0yX1JTaXBhOWxWcjlndmZJNEFiRkFCTFRxS2V0bzByV1BiSUJLZGhjR1E3Sk1QeHpxODIzOUtQVVpmU3lOdWVBY2RMLXlIQURpM0wyVlN6ZEY3dFM3c2kzdWVfSUZvWERwYmdnc0Z4dkV0NzlVbEJET0JzYWdjX21zOV9ac1lsSmFLQ1Q4Wmp3aGFrTW9fLVpkYzk3bXVkVmoxanoyX0w1bDRsX3ppYkY1cml3In0sInBhcmFtZXRlcnMiOnsic3JjSW5pdGlhdG9ySWQiOiJQVVBWVk1BTFNKUUdET0lKRDFQSTIxYTktdlpUbHFWV3FyNm13TkYzWTEyTllPR3lrIiwic3JjaURwYUlkIjoiNDdkOGEzYTYtZjExYS00MGJkLTkzMGQtYWMwYmEyMWQ1M2E4Iiwic3JjaVRyYW5zYWN0aW9uSWQiOiI4Y2MzYjc0Ny03ODhlLTRkY2ItYjUxMi03ZDcyMDIxNDcwNWIiLCJkcGFUcmFuc2FjdGlvbk9wdGlvbnMiOnsiZHBhTG9jYWxlIjoiZW4iLCJwYXlsb2FkVHlwZUluZGljYXRvciI6IkZVTEwiLCJyZXZpZXdBY3Rpb24iOiJjb250aW51ZSIsImRwYUFjY2VwdGVkQmlsbGluZ0NvdW50cmllcyI6W10sImRwYUFjY2VwdGVkU2hpcHBpbmdDb3VudHJpZXMiOlsiTVkiXSwiZHBhQmlsbGluZ1ByZWZlcmVuY2UiOiJOT05FIiwiZHBhU2hpcHBpbmdQcmVmZXJlbmNlIjoiTk9ORSIsImNvbnN1bWVyTmFtZVJlcXVlc3RlZCI6dHJ1ZSwiY29uc3VtZXJFbWFpbEFkZHJlc3NSZXF1ZXN0ZWQiOnRydWUsImNvbnN1bWVyUGhvbmVOdW1iZXJSZXF1ZXN0ZWQiOmZhbHNlLCJtZXJjaGFudENvdW50cnlDb2RlIjoiTVkiLCJjdXN0b21JbnB1dERhdGEiOnsiY2hlY2tvdXRPcmNoZXN0cmF0b3IiOiJtZXJjaGFudCJ9LCJ0cmFuc2FjdGlvbkFtb3VudCI6eyJ0cmFuc2FjdGlvbkFtb3VudCI6IjEwLjAwIiwidHJhbnNhY3Rpb25DdXJyZW5jeUNvZGUiOiJNWVIifSwicGF5bWVudE9wdGlvbnMiOnsiZHBhRHluYW1pY0RhdGFUdGxNaW51dGVzIjoxNSwiZHBhUGFuUmVxdWVzdGVkIjpmYWxzZSwiZHluYW1pY0RhdGFUeXBlIjoiQ0FSRF9BUFBMSUNBVElPTl9DUllQVE9HUkFNX0xPTkdfRk9STSJ9fX19LCJTUkNNQVNURVJDQVJEIjp7Im9yaWdpbiI6Imh0dHBzOi8vc3JjLm1hc3RlcmNhcmQuY29tIiwicGF0aCI6Ii9zZGsvc3Jjc2RrLm1hc3RlcmNhcmQuanMiLCJwYW5FbmNyeXB0aW9uS2V5Ijp7Imt0eSI6IlJTQSIsImUiOiJBUUFCIiwidXNlIjoiZW5jIiwia2lkIjoiMjAyMzAyMjcxMzU2MDMtcHJvZC1mcGFuLWVuY3J5cHRpb24tc3JjLW1hc3RlcmNhcmQtaW50Iiwia2V5X29wcyI6WyJlbmNyeXB0Iiwid3JhcEtleSJdLCJhbGciOiJSU0EtT0FFUC0yNTYiLCJuIjoienh3SHF1elJKRnlfRkhXS2xaeDNxZkhNSElLS1dJaklSZnJDOWV0dVZPN2RDOHYyUlgxbG1wRmdpQTZKeHRiU20tZGFpbTc5U2ZrNnJQc05mUHVKT3VlbzlRYlgxUWlWZVJ3NmR1VU5OeTdtZ0w4bHpuaHRBNWhoOF9WZngxYXduR3E2TFUxX3lfeXd2QXhkcm0zS0djTVp2VUFKYS0wVUFoTFBJTF8tT1c1TjVlSVFQVGczbklyaVlNY0RZMXBENTRGQVRJYnFQQU5NVUVybVN6VVJtRktPdTZUblJnVTFueDg4czBRR0p5eU00SC1qUnh3N0g4OWV0UjlUeERwUjI0OE5WTmZURXczWXpIUmE1WnZkcTNpVHVGWk9YcmxkRGFsNGhIYzY2WkZTclc1STc2MHllQ3gxMVRTdUlxaDhnS2VIN2ZEdmRlNG9ibmdqNkx4MmJ3In0sInBhcmFtZXRlcnMiOnsic3JjaVRyYW5zYWN0aW9uSWQiOiI4Y2MzYjc0Ny03ODhlLTRkY2ItYjUxMi03ZDcyMDIxNDcwNWIiLCJzcmNpRHBhSWQiOiI0N2Q4YTNhNi1mMTFhLTQwYmQtOTMwZC1hYzBiYTIxZDUzYTgiLCJzcmNJbml0aWF0b3JJZCI6IjVmMDg4ODA1LTU4Y2ItNDBlYi05MTdiLWFiOWIxM2ZhYjIxYSIsImRwYVRyYW5zYWN0aW9uT3B0aW9ucyI6eyJ0cmFuc2FjdGlvblR5cGUiOiJQVVJDSEFTRSIsImRwYUxvY2FsZSI6ImVuIiwiZHBhQWNjZXB0ZWRTaGlwcGluZ0NvdW50cmllcyI6WyJNWSJdLCJjb25zdW1lckVtYWlsQWRkcmVzc1JlcXVlc3RlZCI6dHJ1ZSwiY29uc3VtZXJQaG9uZU51bWJlclJlcXVlc3RlZCI6ZmFsc2UsInRyYW5zYWN0aW9uQW1vdW50Ijp7InRyYW5zYWN0aW9uQW1vdW50IjoiMTAuMDAiLCJ0cmFuc2FjdGlvbkN1cnJlbmN5Q29kZSI6Ik1ZUiJ9LCJkcGFBY2NlcHRlZEJpbGxpbmdDb3VudHJpZXMiOltdLCJkcGFCaWxsaW5nUHJlZmVyZW5jZSI6Ik5PTkUiLCJkcGFTaGlwcGluZ1ByZWZlcmVuY2UiOiJOT05FIiwiY29uc3VtZXJOYW1lUmVxdWVzdGVkIjp0cnVlLCJwYXlsb2FkVHlwZUluZGljYXRvciI6IkZVTEwiLCJwYXltZW50T3B0aW9ucyI6eyJkeW5hbWljRGF0YVR5cGUiOiJDQVJEX0FQUExJQ0FUSU9OX0NSWVBUT0dSQU1fU0hPUlRfRk9STSJ9fX19fSwidGFyZ2V0T3JpZ2lucyI6WyJodHRwczovL3Bndy11aS4yYzJwLmNvbSJdLCJpZnJhbWVzIjp7Im1jZSI6Ii9tY2UvbWNlLmh0bWwiLCJidXR0b25zIjoiL2J1dHRvbmxpc3QvYnV0dG9ubGlzdC5odG1sIiwic3JjIjoiL3NlY3VyZS1yZW1vdGUtY29tbWVyY2Uvc3JjLmh0bWwiLCJjdHAiOiIvY3RwL2N0cC5odG1sIiwiZ29vZ2xlcGF5IjoiL2dvb2dsZXBheS9nb29nbGVwYXkuaHRtbCIsImFwcGxlcGF5IjoiL2FwcGxlcGF5L2FwcGxlcGF5Lmh0bWwiLCJwYXplIjoiL3BhemUvcGF6ZS5odG1sIiwiY2hlY2siOiIvY2hlY2svY2hlY2suaHRtbCIsImdhIjoiL2dhL2dhLmh0bWwiLCJvcmMiOiIvb3JjL29yYy5odG1sIiwidG0iOiIvdG0vdG0uaHRtbCIsImFwbSI6Ii9hcG0vYXBtLmh0bWwifSwiY2xpZW50VmVyc2lvbiI6IjAuMjgiLCJjb3VudHJ5IjoiTVkiLCJsb2NhbGUiOiJlbiIsImFsbG93ZWRDYXJkTmV0d29ya3MiOlsiTUFTVEVSQ0FSRCIsIlZJU0EiXSwiYW5hbHl0aWNzIjp7Imdvb2dsZSI6eyJzY3JpcHQiOiJodHRwczovL3d3dy5nb29nbGV0YWdtYW5hZ2VyLmNvbS9ndGFnL2pzIiwiaWQiOiJHLVBUMlJZOFYxNkQifSwiZXZlbnRHcm91cElkIjoiMWNOWktDRGtaTFYxSDNjdVFXMEpRektqS0xGNXE0ZEN3VElIN1ZFQXpfLXZsbFphTnd5LTVtNWxUUzJ3Xy1RIn0sImNyIjoib0RwN1ZhXzFOUWtWa3ZIS08wRFduY3Vsd2gwcHlnWURJRGtOaVgxZnRBbWRwcHFLNGtYYVpiQk05N2UxSkFabVktXzE2WkpPMlA3cW9BMkx5cnFVWklDZVJmakIzWl9oSVdONXVMMV9KX2RwNDZsUE93UnBWVUc1amxBblIyYUtQUHF1ZlM3d3Y3R1RJeEUiLCJzZXJ2aWNlT3JpZ2luIjoiaHR0cHM6Ly91cC5jeWJlcnNvdXJjZS5jb20iLCJjbGllbnRMaWJyYXJ5IjoiaHR0cHM6Ly91cC5jeWJlcnNvdXJjZS5jb20vdWMvdjEvYXNzZXRzLzAuMjguMy9TZWN1cmVBY2NlcHRhbmNlLmpzIiwibG9nZ2luZ1BhdGgiOiIvdWMvdjEvbG9nLWV2ZW50cyIsImFzc2V0c1BhdGgiOiIvdWMvdjEvYXNzZXRzLzAuMjguMyIsImNsaWVudExpYnJhcnlJbnRlZ3JpdHkiOiJzaGEyNTYtM3Z4M2dXamwreEphOUpaYS9lS0E5VTFFRTVMWE5qMGxHN3JXUW12cS9uUVx1MDAzZCJ9LCJ0eXBlIjoiZ2RhLTAuMTAuMCJ9XSwiaXNzIjoiRmxleCBBUEkiLCJleHAiOjE3NzIxNjU3MTYsImlhdCI6MTc3MjE2NDgxNiwianRpIjoiY0NVVjRVVnBxSzZMY3NVTCJ9.mMdzEKmwvdHVDEtAKfUubGax4981z0m1CHKDDtGzhrfUWh8Y3nJ1uLL50ny1KaA6JFx8mqtf6yFnSdH3XZxbbOFzaob5beXqtSQnHuBjWOJ75kgHVjtxxg7pAsdZASnW5bBfcmavkiPZas1K7V5HJvh9XEivM5kYr_6q3iMZKMk7M6QD-ts2gcTItfoYX-29wUiUCZABwqkPQj3aQLSVmnDP1vU_j7nPaW9xlUAyW01_yOMqcyWHpHS4ZhQ19tG3JoCbsleasFj2drzm9Tf5XYvGxPRDMmkPXRSeMYxX-ieVd4vEXBwoLN_Zk07BwABO3D_ETZr1-2dAiWdIJolW8g",
"srcUrl": "https://testup.cybersource.com/uc/v1/assets/0.28.3/SecureAcceptance.js"
},
"isDown": false,
"CheckEligibleOption": false,
"ippProviderCode": null,
"registrationStatus": null,
"partnerMerchantRefID": null,
"displayProcessingAmount": false,
"supportsTokenization": false,
"clickToPayEnabled": false,
"requiredTxnStatusInquiry": false,
"SupportPaySimulate": false
}
}
],
"validation": null,
"configuration": {
"payment": {
"tokenize": false,
"tokenizeOnly": false,
"cardTokenOnly": false,
"immediatePayment": true,
"fx": {}
},
"notification": {
"facebook": false,
"whatsApp": false,
"line": false
}
},
"respCode": "0000",
"respDesc": "Success"
}Populate click2pay event() & button
To populate click2pay event and button, captureContextToken data is required
<script>
function loadClick2PayButton(captureContextToken){
var captureContextToken =
const click2PayWindow = window;
if (!click2PayWindow.Accept) {
console.error("Accept() not found. UC script not loaded.");
return;
}
click2PayWindow.Accept(captureContextToken)
.then(function (accept) {
return accept.unifiedPayments();
})
.then(function (up) {
return up.show(showArgs);
})
.then(function (result) {
// call do payment api with return token
submitPayment(result);
})
.catch(function (err) {
console.error("UC error", err);
});
}
//control the click2pay button
const showArgs = {
containers: {
paymentSelection: "#payment-container"
},
locale: "en_US"
};
</script>Submit Payment via Do Payment API
To specific request for click2pay, required to send
- payment.data.token : token from click2pay
- payment.code.channelCode :
CLICK2PAY
{
"payment": {
"data": {
"token": "eyJraWQiOiIwOGFxd2JkeXJOU0RIbHh3MFZCMGp2Z2Z3ZU00MFhzayIsImFsZyI6IlJTMjU2In0.eyJtZXRhZGF0YSI6eyJjYXJkaG9sZGVyQXV0aGVudGljYXRpb25TdGF0dXMiOmZhbHNlLCJwYXltZW50VHlwZSI6IlBBTkVOVFJZIn0sImlzcyI6IkZsZXgvMDgiLCJwYXltZW50Q3JlZGVudGlhbHNSZWZlcmVuY2UiOnsiMmMycF9zYW5kYm94IjoiRU1keS12UGlSd2JrYTR3TTVaY1h2In0sImV4cCI6MTc3MjE3MzM3OCwidHlwZSI6ImdkYS0wLjEwLjAiLCJpYXQiOjE3NzIxNzI0NzgsImp0aSI6IjFFMDJYMVA4U09ZSlg3Rk5ONEFGT0dKSjI2UFo5SDhPS1o3OVE5VUJKWkRYUEhOQ0RZRTA2OUExMzg0Mjc5MjQiLCJjb250ZW50Ijp7Im9yZGVySW5mb3JtYXRpb24iOnsiYmlsbFRvIjp7ImNvdW50cnkiOnt9LCJsYXN0TmFtZSI6e30sImZpcnN0TmFtZSI6e30sImVtYWlsIjp7fX0sImFtb3VudERldGFpbHMiOnsidG90YWxBbW91bnQiOnt9LCJjdXJyZW5jeSI6e319fSwicGF5bWVudEluZm9ybWF0aW9uIjp7ImNhcmQiOnsiZXhwaXJhdGlvblllYXIiOnsidmFsdWUiOiIyMDI4In0sIm51bWJlciI6eyJtYXNrZWRWYWx1ZSI6IlhYWFhYWFhYWFhYWDExMTEiLCJiaW4iOiI0MTExMTEifSwic2VjdXJpdHlDb2RlIjp7fSwiZXhwaXJhdGlvbk1vbnRoIjp7InZhbHVlIjoiMDMifSwidHlwZVNlbGVjdGlvbkluZGljYXRvciI6eyJ2YWx1ZSI6IjEifSwidHlwZSI6eyJ2YWx1ZSI6IjAwMSJ9fX19fQ.OK5xYmXAFEWJw-YWBKcb70J1d7KIJxZB_l0wFtGsP8LdGvMG_ihQ53siiFuqUvH72PBVX0OoQDrL9clg-J72ivTTnH5G-qlpZIRXh7qzFll3gcw0xb_lKUf4rLUVOa33HcXfV9QJCWx3tBJyqZ_Mx-eGMS0A_sAx2l1uC4P_taJ9dXJrDN7AOaH1qQRMWr_m0jBujhVVWYBFlE7Rx5mHcNWGZ1BuxJF9Pn8NR0O2WLHdub4VFm_lWgLZK-a-fbjfBkc635qjgUivLeAGiNdQu2ywwA6TtkxzZ1y-TEWliqqkwjx6YcnKGmEpWhBP_tWYOL0XczNpErA1wFb8O1VEYg"
},
"code": {
"channelCode": "CLICK2PAY"
}
},
"paymentToken": "kSAops9Zwhos8hSTSeLTUZ/goBdhnDMvyGuHBEHQqL2GuUEfQDEVxQ4gc+Fovrclau1BRVuOSSK9njQZCzgFJtPIMtNDBsADV76rcWV75eVvVj3cbNFhfIYADvw0rF4eQjS0a09AoemPBOFO+X9cvw=="
}Full Sample Code
<!DOCTYPE html>
<html>
<body>
<button id="paysubmit" onClick="initialPay()">Submit</button>
<div id="payment-container"></div> <!--to show click to pay button-->
<script src="https://testup.cybersource.com/uc/v1/assets/0.28.2/SecureAcceptance.js"></script>
<script>
var endpoint = "https://sandbox-pgw.2c2p.com";
var merchantDomain = "https://www.2c2p.com";
var click2Paytoken;
function initialPay(){
//Call Payment token API
//Dummy payment token just for testing
var paymentToken = "kSAops9Zwhos8hSTSeLTUdidclqi6ZtWWFG8cIOIXZvc+Gxmk0gyH6NhQPROKBAWtwaXFypz7QdPjPohVr63ar4Qu3tpOJc90ugyQS9nqP+1GshjNKo1i8CuZ3PI3s25Boz1W8oIVezuY/trNtBF5g==";
onSubmitCaptureContext(paymentToken);
}
function onSubmitCaptureContext(paymentToken){
const headers = {
"Content-Type": "application/json"
};
headers["X-Merchant-Domain"] = merchantDomain;
fetch(`${endpoint}/payment/4.3/PaymentOptionDetails`, {
method: "POST",
headers,
body: JSON.stringify({
paymentToken: paymentToken,
categoryCode: "DPAY",
groupCode: "CWALLET"
})
})
.then(res => res.json())
.then(data => {
//Retrieve token, use loop to find channelCode=CLICK2PAY
for(var i=0; i< data.channels.length; i++ ){
if(data.channels[i].payment.code.channelCode == "CLICK2PAY"){
click2Paytoken = data.channels[i].payment.info.token;
}
}
loadClick2PayButton(click2Paytoken);
})
.catch(err => {
console.error("Payment error:", err);
});
}
function submitPayment(transientToken){
var returnUrl = "https://sandbox-pgw-ui.2c2p.com/payment/4.3/#/info/";
const payload = {
paymentToken,
responseReturnUrl: returnUrl,
payment: {
code: {
channelCode: "CLICK2PAY"
},
data: {
token: transientToken
}
}
};
try {
const res = fetch(`${endpoint}/payment/4.3/payment`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(res => {
console.log("Payment response:", res);
if (
res.respCode === "1001" ||
res.respCode === "1002" ||
res.respCode === "1004"
) {
window.open(res.data, "_self");
}
});
} catch (err) {
console.error("Payment error:", err);
}
}
//control the click2pay button
const showArgs = {
containers: {
paymentSelection: "#payment-container"
},
locale: "en_US"
};
function loadClick2PayButton(captureContextToken){
const click2PayWindow = window;
if (!click2PayWindow.Accept) {
console.error("Accept() not found. UC script not loaded.");
return;
}
click2PayWindow.Accept(captureContextToken)
.then(function (accept) {
return accept.unifiedPayments();
})
.then(function (up) {
return up.show(showArgs);
})
.then(function (result) {
submitPayment(result);
})
.catch(function (err) {
console.error("UC error", err);
});
}
</script>
</body>
</html>Updated about 5 hours ago
