Add the CardCorp iframe checkout to your website and collect instalment payments
Learn the payment flow for an instalment payments integration where the customer pays a deposit with the iframe checkout and then you collect recurring payments.
1. Create the checkout in the payment gateway
The first step is to perform a POST
request to the payment gateway to create a checkout, with the payment type, amount, currency, and required attributes.
Here is an example request to create a checkout for the initial payment of an instalment order.
curl https://eu-test.oppwa.com/v1/checkouts \
-H "Accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
-d "entityId={channelId}" \
-d "amount=20.05" \
-d "currency=EUR" \
-d "paymentType=DB" \
-d "integrity=true" \
-d "merchantTransactionId=P128" \
-d "billing.street1=Ave. Diagonal 611" \
-d "billing.city=Barcelona" \
-d "billing.country=ES" \
-d "billing.postcode=08028" \
-d "standingInstruction.type=INSTALLMENT" \
-d "standingInstruction.mode=INITIAL" \
-d "standingInstruction.source=CIT" \
-d "standingInstruction.numberOfInstallments=999" \
-d "standingInstruction.expiry=9999-12-31" \
-d "standingInstruction.frequency=0001" \
-d "createRegistration=true" \
-d "[email protected]" \
-d "customer.ip=2001:8a0:7f4b:1b00:dd4e:2bf6:1fb8:56af" \
-d "customer.givenName=John" \
-d "customer.surname=Smith" \
-d "customer.phone=34667666666" \
-d "customer.merchantCustomerId=CUST01" \
-d "threeDSecure.challengeIndicator=04" \
-d "customParameters[StoreCredentialType]=CIT" \
-d "customParameters[CRMCustomerID]=CRM CUST01" \
-d "customParameters[InstalmentsID]=I-00100" \
-d "customParameters[PaymentType]=Instalment" \
-d "customParameters[3DS2_enrolled]=true" \
-d "customParameters[3DS2_flow]=challenge" \
-d "testMode=EXTERNAL" \
-H "Authorization: Bearer {auth_token}"
Replace the example values with your values and replace the {channelId}
and {auth_token}
with your API credentials.
Here are some notes about the parameters in this request.
Parameters | Notes |
---|---|
paymentType | Can be DB ("debit") or PA ("preauthorization"). For PA , use the back-office API to capture the payment. |
merchantTransactionId | We recommend that you provide a unique identifier for each transaction. |
billing address | The billing address is required if you use 3DS verification; otherwise, it is recommended. |
standingInstruction.type | Set to INSTALLMENT to specify an instalment order. Note the spelling of instalment with a double L . |
standingInstruction.mode | Set to INITIAL to specify the first payment where you are saving a card |
standingInstruction.source | Set to CIT to specify a customer-initiated transaction. |
standingInstruction.numberOfInstallments | Set to 999 to create a flexible instalment order |
standingInstruction.expiry | Set to 9999-12-31 to create a flexible instalment order. |
standingInstruction.frequency | Set to 0001 to create a flexible instalment order. |
createRegistration | Set to true to save the customer's card for future payments. |
customer details | We recommend you supply customer details, including a unique identifier for each customer. |
threeDSecure.challengeIndicator | The recommended value is 04 . This means that 3DS is mandated in your region, and it tells the issuer to define the challenge type. |
customParameters | We recommend that you add custom parameters to uniquely identify the transaction initiation type, customer, order, and purchase type. The custom data you send in these parameters will be returned in the payment response. You can use these parameters to pair and match information from the payment gateway with your business systems. You can create an unlimited number of unique and properly-named custom parameters. |
When you are testing your integration, you can use the following parameters.
Parameters | Notes |
---|---|
customParameters[3DS2_enrolled][3DS2_enrolled] | This parameter is for the test environment only. Set to true for any card to specify that the card is enrolled in 3DS. Or, instead of the 3DS test parameters, you can use 3DS test cards. |
customParameters[3DS2_flow][3DS2_flow] | This parameter is for the test environment only. Set to challenge to force a 3DS challenge, or frictionless . Or, instead of the 3DS test parameters, you can use 3DS test cards. |
testMode | This parameter is for the test environment only. Set to EXTERNAL to send the transaction to the acquirer's test environment. Set to INTERNAL to process the transaction in the gateway only. |
For more details of 3DS testing, see the Gateway 3DS testing guide
For full details of all the parameters, see the Gateway API reference.
Your successful request will receive a JSON response.
Response Example:
{
"result":{
"code":"000.200.100",
"description":"successfully created checkout"
},
"buildNumber":"d7f3057c29b9a26d5151336767387bb393720d7e@2024-10-14 09:16:49 +0000",
"timestamp":"2024-10-15 15:16:31+0000",
"ndc":"FB76D9A1B7D1CAC70A03923F903F74FB.uat01-vm-tx03",
"id":"FB76D9A1B7D1CAC70A03923F903F74FB.uat01-vm-tx03",
"integrity":"sha384-/j1gGQsS/nAgGp9u7LjRlD7nwA3h+yXS5aEP/vbzrbpgPWuRDhCuFok3J8lWVC3X"
}
From this response, you will need the value of the id
and integrity
for the next step.
2. Create the payment form on your web page
To create the payment form on your web page, add the following lines of JavaScript and HTML and enter the following variables.
- This script gets the checkout from the payment gateway. Replace the
{checkoutId}
with the value of theid
and replace{integrity}
with the value ofintegrity
from the response in Step 1. Replaceanonymous
with the address of your website that loads the COPYandPAY checkout.
<script
src="https://eu-test.oppwa.com/v1/paymentWidgets.js?checkoutId={checkoutId}"
integrity="{integrity}"
crossorigin="anonymous">
</script>
- This HTML displays the checkout. The
shopperResultUrl
is a page on your site where the customer should be redirected after payment processing.
<form action="{shopperResultUrl}" class="paymentWidgets" data-brands="VISA MASTER"></form>
For example, a checkout script could look like this.
<script src="https://eu-test.oppwa.com/v1/paymentWidgets.js?checkoutId=702B930F656317E0D29A22D195F75A59.uat01-vm-tx03"
integrity="sha384-KnYRC1jbE3C9SMGbJ5eU2Gx+AM9PCaApfqS6lk8MpPlvk9jIii4PFu297dPu4wcy"
crossorigin="https://example.com">
</script>
For example, your checkout HTML could look as follows.
<form action="https://myshop.example.com/paid" class="paymentWidgets" data-brands="VISA MASTER"></form>
You can use the same checkout ID multiple times to retrieve a valid payment form. If a customer does
not finish the payment and then reloads the page or uses the browser's back button, you do not need to create a new checkout, but these actions can result in multiple transactions in the system. For example, there can be one or more failed transactions and one successful transaction from the same checkout ID.
The checkout expires in 30 minutes, and after it expires, you must renew the checkout. Send a new request to create a checkout and use the new checkoutId
to create the payment form again.
Customise the payment widget
To customise the payment widget to match the look of your own site, see this customisation guide and the advanced options guide.
You can also add extra fields to this form, for example, to obtain the customer details during checkout.
To display some sample customisations, go to demo checkouts. You can obtain the code for the demo checkouts at Demo checkouts on GitHub.
Here is an example of a basic instalment payment iframe customisation.

Basic iframe customisation
3. Get payment status from the checkout in the gateway
When the payment has been processed, CardCorp will redirect the customer to your shopperResultUrl
.
To get the payment status, make a GET request to the payment link of your checkout in the gateway, as follows.
curl -G https://eu-test.oppwa.com/v1/checkouts/{id}/payment \
-d "entityId=8ac7a4ca73522ba8017353bdfb9b0639" \
-H "Authorization: Bearer {auth_token}"
Replace the {id}
and the {auth_token}
with your values.
Here is an example of the result of a successful payment.
{
"id":"8ac7a4a1913510db0191363e7df14abc",
"registrationId":"8ac7a4a2913518d801913615c8e01104",
"processingEntityId":"{channelId}",
"paymentType":"DB",
"paymentBrand":"MASTER",
"amount":"400.00",
"currency":"EUR",
"descriptor":"3001.6111.5167 ECOMChannel",
"merchantTransactionId":"P130",
"recurringType":"INITIAL",
"result":{
"cvvResponse":"U",
"code":"000.100.112",
"description":"Request successfully processed in 'Merchant in Connector Test Mode'"
},
"resultDetails":{
"ExtendedDescription":"Approved",
"usedChallengeIndicator":"04",
"clearingInstituteName":"SecureTrading Omnipay Demo",
"ConnectorTxID1":"866380||true|UMCC634161 ||0809|029| ||INSTALLMENT|80||false|false|false|812|2",
"connectorId":"422207866380",
"ConnectorTxID3":"422207866380|00|||1||0809074128|||||||||||||Berlin|",
"ConnectorTxID2":"697761||8ac7a0b39134af7f01913615dffe04dd",
"AcquirerResponse":"00",
"reconciliationId":"3001.6111.5167",
"CardholderInitiatedTransactionID":"MCC6341610809",
"SchemeResponseCode":"00"
},
"card":{
"bin":"520000",
"binCountry":"MY",
"last4Digits":"0049",
"holder":"John Smith",
"expiryMonth":"02",
"expiryYear":"2027",
"issuer":{
"bank":"PUBLIC BANK BERHAD",
"website":"HTTPS://WWW.PBEBANK.COM/",
"phone":"1-800-22-5555"
},
"type":"CREDIT",
"level":"STANDARD",
"country":"MY",
"maxPanLength":"16",
"binType":"PERSONAL",
"regulatedFlag":"N"
},
"customer":{
"givenName":"John",
"surname":"Smith",
"merchantCustomerId":"CUST05",
"phone":"34667666666",
"email":"[email protected]",
"ip":"2001:8a0:7f4b:1b00:dd4e:2bf6:1fb8:56af"
},
"billing":{
"street1":"Calle Principal 123",
"city":"Barcelona",
"postcode":"08028",
"country":"ES"
},
"threeDSecure":{
"eci":"02",
"version":"2.2.0",
"dsTransactionId":"3e3ab66a-8e7e-4633-ae66-6df9e2ed64d9",
"challengeMandatedIndicator":"N",
"transactionStatusReason":"17",
"acsTransactionId":"57974929-a019-4f4d-ae98-75ef5fc29ea1",
"cardHolderInfo":"",
"authType":"01",
"flow":"challenge",
"authenticationTimestamp":"202408090741",
"authenticationStatus":"Y"
},
"customParameters":{
"StandingInstructionAPI":"true",
"3DS_enrolled":"true",
"SHOPPER_EndToEndIdentity":"e13a1b714f9eea149348dc9bdcf2878f1b1770dd793bea79cb64981c9c15d283",
"CTPE_DESCRIPTOR_TEMPLATE":"",
"InstalmentsID":"I-00101",
"StoredCredentialType":"CIT",
"PaymentType":"Instalment",
"CRMCustomerID":"CRM-CUST05",
"3DS2_flow":"challenge",
"StoreCredentialType":"CIT"
},
"risk":{
"score":"0"
},
"buildNumber":"174903ec91870d5654938dd40f55da3b35036b23@2024-08-08 12:50:27 +0000",
"timestamp":"2024-08-09 07:41:28+0000",
"ndc":"02538F39CDCD6BE78BFE4F81E452DE3B.uat01-vm-tx03",
"standingInstruction":{
"source":"CIT",
"type":"INSTALLMENT",
"mode":"INITIAL",
"initialTransactionId":"MCC6341610809",
"expiry":"9999-12-31",
"frequency":"0001",
"numberOfInstallments":"999"
},
"source":"OPPUI",
"paymentMethod":"CC",
"shortId":"3001.6111.5167"
}
To interpret the payment response, see Transaction results.
To collect a repeated payment for an instalment order, you will need the card registrationId
and the CardholderInitiatedTransactionID
from the approved payment result.
There is a request limit for payment status calls, after which the gateway will reduce your access to the endpoint with throttling. You can send two (2) GET
payment requests per minute for each checkout ID.
When you get the payment response status, compare the returned values with the expected values for the following fields: ID(s), amount, currency, brand and type.
After a payment response status is successful, you cannot use the checkout identifier again. So if you need to get the status, use the Transaction Reports endpoint with the payment id
. You will also need the id
to manage payments with the Backoffice API. See Backoffice API operations.
4. Collect a repeated payment for an instalment order
After you have taken a deposit and saved the customer's card, you can use the payments API to collect a repeated payment for an instalment order. You will need the cardholder-initiated transaction identifier from the initial payment.
Perform a POST
request to the payment gateway to collect a repeated payment for an instalment order.
curl https://eu-test.oppwa.com/v1/registrations/{registrationId}/payments \
-H "Accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
-d "entityId={channelId}" \
-d "amount=20.06" \
-d "currency=EUR" \
-d "paymentType=DB" \
-d "merchantTransactionId=P129" \
-d "standingInstruction.type=INSTALLMENT" \
-d "standingInstruction.mode=REPEATED" \
-d "standingInstruction.source=MIT" \
-d "standingInstruction.initialTransactionId={CardholderInitiatedTransactionID}" \
-d "customer.ip=2001:8a0:7f4b:1b00:dd4e:2bf6:1fb8:56af" \
-d "customParameters[CRMCustomerID]=CUST01" \
-d "customParameters[InstalmentsID]=I-00100" \
-d "customParameters[TransactionID]=P-00006000" \
-d "customParameters[StoreCredentialType]=MIT" \
-d "testMode=EXTERNAL" \
-H "Authorization: Bearer {auth_token}"
Replace the example values with your values and replace the {channelId}
and {auth_token}
with your API credentials, and replace the {CardholderInitiatedTransactionID}
with the value from your initial transaction.
Here are some notes about the parameters in this request.
Parameters | Notes |
---|---|
paymentType | Can be DB ("debit"), PA ("preauthorization"). For PA , use the back-office API to capture the payment. |
merchantTransactionId | We recommend that you provide a unique identifier for each transaction. |
standingInstruction.type | Set to INSTALLMENT to specify an instalment order. Note the spelling of instalment with a double L . |
standingInstruction.mode | Set to REPEATED to specify a repeated payment using a saved card |
standingInstruction.source | Set to MIT to specify a merchant-initiated transaction where the customer is not present. |
CardHolderInitiatedTransactionID | Use the value of the CardHolderInitiatedTransactionID that you obtained from the results of the initial payment. |
customer details | We recommend that you supply the customer's IP address. |
customParameters | We recommend that you add custom parameters to uniquely identify the transaction initiation type, customer, order, and purchase type. The custom data you send in these parameters will be returned in the payment response. You can use these parameters to pair and match information from the payment gateway with your business systems. You can create an unlimited number of unique and properly-named custom parameters. |
When you are testing your integration, you can use the following parameters.
Parameter | Notes |
---|---|
testMode | This parameter is for the test environment only. Set to INTERNAL to process the transaction in the gateway only. Set to EXTERNAL to send the transaction to the acquirer's test environment. |
You will receive a JSON response like the one below, which shows an approved payment.
{
"id": "{channelId}",
"paymentType": "DB",
"amount": "400.00",
"currency": "EUR",
"descriptor": "6928.7758.3391 ECOMChannel ",
"merchantTransactionId": "P135",
"result": {
"code": "000.100.112",
"description": "Request successfully processed in 'Merchant in Connector Test Mode'"
},
"resultDetails": {
"ExtendedDescription": "Approved",
"clearingInstituteName": "SecureTrading Omnipay Demo",
"ConnectorTxID1": "867809||false| MCC634196 ||0809|| ||INSTALLMENT|80||true|true|false|812|2",
"ConnectorTxID3": "422208867809|00|||1||0809080059|||||||||||||Berlin|",
"connectorId": "422208867809",
"ConnectorTxID2": "137298||8ac7a0b39134af7f01913627bed70511",
"AcquirerResponse": "00",
"reconciliationId": "6928.7758.3391",
"merchantAccountId": "8ac7a4c890fc748b0190fe70998c0248",
"CardholderInitiatedTransactionID": "MCC6341960809",
"SchemeResponseCode": "00"
},
"customer": {
"ip": "2001:8a0:7f4b:1b00:dd4e:2bf6:1fb8:56af"
},
"customParameters": {
"CRMCustomerID": "CUST01",
"InstalmentsID": "I-00100",
"StoreCredentialType": "MIT",
"TransactionID": "P-00006000"
},
"risk": {
"score": "0"
},
"buildNumber": "174903ec91870d5654938dd40f55da3b35036b23@2024-08-08 12:50:27 +0000",
"timestamp": "2024-08-09 08:01:00+0000",
"ndc": "8ac7a4c890fc748b0190fe6ad56b0241_dc3e169a224849178aa8da7a63c2f245",
"standingInstruction": {
"source": "MIT",
"type": "INSTALLMENT",
"mode": "REPEATED",
"initialTransactionId": "MCC6341960809"
},
"source": "OPP",
"paymentMethod": "CC",
"shortId": "6928.7758.3391"
}
To interpret the payment response, see Transaction results. As before, you can use the id
to manage the payment with the Backoffice API. See Backoffice API operations.
View the full technical integration guide
The integration guide provides a comprehensive playground with code samples in all major programming languages.
Integration Guide. For request data that you can use in the playground, see Gateway playground COPYandPAY data
Questions? - Sign up on our website and talk to our payment experts to learn more about integrating our iFrame checkout.