COPYandPAY is a SAQ-A compliant payment-form solution, making it both secure and simple-to-integrate.

The info below is additional information for product owners and project managers to understand the two main transaction flows to store a card.

There are two workflows for card storage.

OPTION 1 - Card storage with a checkout
OPTION 2 - Card storage without a checkout

We breakdown the two options below. 
NB!! - Note that this article is a guide and should be used in conjunction with the CopyAndPay API documentation available here to get the exact parameters and sample code.


- Customer selects a product or service
- At the payment step, the card is also stored


Since there is no checkout when a customer adds a card ; i.e,. your workflow could be

- Customer creates profile (on your system)
- Add a card to profile
- Your system stores the card

The customer can then make payments with their stored card(s) at a later stage, when they are ready to checkout.

For this standalone card storage, change the CheckoutID request from Step 1 CopyAndPay (screenshot below) to include the following :

paymentType = PA
Amount = 1.00

Here is a screenshot of our technical documentation, showing the payment request to prepare the card storage checkout. 


1. Send request to store the card

A R1.00 PA is done to check that the card being added is valid, before you store the card for future billing.

This R1.00 amount should return to the customer's account after a period ; i.e, their balance will increase by R1.00 when the PA falls away (reservation period differs from bank to bank).

Sample code below:

curl \
-d "amount=1.00" \
-d "currency=ZAR" \
-d "paymentType=PA" \
-d "createRegistration=true \


You can then store the card (the registrationID) in your database against the customer's user profile, ONLY IF the PA transaction is successful.

Please use the 3-DSecure channel ID as the entityId, for this PA transaction. This will make sure the user authenticates the card via 3DSecure with their bank before the card is added.


2. Your systems store card token

The payload (response from our systems) will include a registrationID, which you can save as the token of the card. You can then make payments on this stored card by referencing its token.

NB : Please only store the token in your database if the PA transaction is successful


3. When amount is due, stored card is billed

curl{id}/payments \
-d "amount=92.00" \
-d "currency=ZAR" \
-d "paymentType=DB" \
 -d "recurringType=REPEATED" \

Please note that the entity ID here should be the recurring entityID -d "authentication.entityId=XXXXXXXX" \



If you would want to take the subsequent payments through 3DSecure, then you would use the 3DSecure entityID and remove the recurringType=REPEATED parameter. This will make sure the transaction triggers an OTP for 3DSecure authentication, rather than skip 3DSecure as required for subscription models, with no customer interaction.

The customer will still not need to enter their card number and other details (as these are stored), but they would still authenticate the transaction with an OTP

In this case, you would have

curl{id}/payments \
-d "amount=92.00" \
-d "currency=ZAR" \
-d "paymentType=DB" \
 -d "recurringType=REPEATED" \

Please note that the entity ID here should be the 3DSECURE entityID -d "authentication.entityId=XXXXXXXX" \

If you only have one entityID, this will by default be the 3DSecure entityID.

Some more notes on this workflow :

Our documentation discusses Standalone tokenisation, which is done without charging the card. It processes an RG transaction only, to store the card.

Main reason why we do not recommend processing a payment type RG (to store the card), is that the RG does not go to the bank and therefore will not be authenticated. The PA transaction ensures that the card is at least tested with the issuing bank and if the PA is successful, you can go ahead and store the card.