There are two workflows for card storage.
OPTION 1 - Card storage with a checkout
OPTION 2 - Card storage without a checkout
If your workflow is :
- Customer adds card
- Your systems store card token
- When the amount is due, the stored card is billed
Please see sample code below - please refer to our technical documentation for conclusive instructions:
Customer adds card
curl https://eu-test.oppwa.com/v1/payments \ entityId=8a8294174e735d0c014e78cf26461790 amount=1.00 currency=ZAR paymentBrand=VISA paymentType=PA card.number= 4111111111111111 card.holder=Jane Jones card.expiryMonth=05 card.expiryYear=2020 card.cvv=123 standingInstruction.mode=INITIAL standingInstruction.type=UNSCHEDULED standingInstruction.source=CIT createRegistration=true shopperResultUrl=https://peachpayments.docs.oppwa.com/tutorials/server-to-server |
This will validate the card and once validated, store the card details and return a payload.
This 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 (period differs from bank to bank).
If this R1.00 PA is not done, first of all the card storage transaction cannot be 3DSecure authenticated and secondly, you may store cards that cannot be billed at a later stage. This does not ensure that you can charge the full amount (since most likely the basket value would be greater than R1.00), but it at least checks with the bank that the card is valid.
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. Please only store the token in your database if the PA transaction is successful
When amount is due, stored card is billed
curl https://eu-test.oppwa.com/v1/registrations/{id}/payments \ -d "entityId=XXXXXXXXXXXXXXXXXXXXXXXXXXX" \ -d "amount=92.00" \ -d "currency=ZAR" \ -d "standingInstruction.mode=REPEATED" \ -d "standingInstruction.type=UNSCHEDULED" \ -d "standingInstruction.source=MIT" \ -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==" |
Please note that the entity ID here should be the recurring entityID -d "authentication.entityId=XXXXXXXX" \
IF you were only supplied one entityID, as long as the recurringType parameter indicates REPEATED, this will still direct the transaction to skip 3DSecure
HOW TO MAKE 3DSECURE SUBSEQUENT PAYMENTS ON STORED CARDS / TOKENS
If you would want to take the subsequent payments through 3DSecure, then you would use the 3DSecure entityID and remove the standingInstruction.mode=REPEATED, standingInstruction.type=UNSCHEDULED and standingInstruction.source=MIT parameters. 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.
In this case, you would have
curl https://eu-test.oppwa.com/v1/registrations/{id}/payments \ -d "entityId=XXXXXXXXXXXXXXXXXXXXXXXXXXX" \ -d "amount=92.00" \ -d "currency=ZAR" \ -d "paymentType=DB" \ -d "standingInstruction.mode=REPEATED" \ -d "standingInstruction.type=UNSCHEDULED" \ -d "standingInstruction.source=MIT" \ -H "Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX==" |
Please note that the entity ID here should be the 3DSECURE entityID -d "entityId=XXXXXXXX" \
If you only have one entityID, this will by default be the 3DSecure entityID.
Please see how to handle the 3DSecure redirect here