Skip to main content
This page puts the whole flow in one place: the cardholder enters a card on your checkout page, completes 3D Secure, and your server charges the card through any supported payment gateway. It has a complete HTML page and a complete server, in Node.js and C#. To see the same flow running before you read the code, open the card entry form demo. See Live Demos for what to try on it.

How the Flow Works

Three things to note:
  • Your API key stays on your server. The browser only gets a session token, which is valid for 5 minutes.
  • The 3D Secure result is stored on the token. You do not pass it to the charge yourself. When the gateway supports 3D Secure data, PCI Booking adds it to the charge automatically. See 3D Secure and the UPG.
  • The charge is an API call from your server. There is no payment page for the gateway, and the cardholder never leaves your page.

Before You Start

You need:
  • A PCI Booking sandbox account and its API key.
  • Your PCI Booking username. The card entry form uses it as the brand parameter.
  • For your first test, nothing else. The examples charge through NULLSuccess, PCI Booking’s built-in test gateway, so you do not need a PSP account yet.
Use the 3D Secure test cards with your sandbox API key. With a live API key, the same cards cannot complete 3D Secure. See Troubleshooting below.

The Checkout Page

Save this as public/checkout.html. It loads the card entry form, uses your own Pay button to submit it, and sends the card token to your server.
checkout.html
Also create public/card-failed.html, a short page that says the card was not accepted. When the card is rejected, the card entry form loads this page inside the iframe, and your page also receives a CardSubmitFailure message. The example then loads a fresh form so the guest can try another card. How the page works:
  • submitWithPostMessage=true removes the form’s own submit button. Your page submits the form by sending it the submit message.
  • postMessageHost must be the exact origin of your page. Without it, the form sends no messages at all.
  • Check event.origin before you act on a message, as the listener above does, and send the form only the documented submit and validate messages.
  • The CardSubmitSuccess message carries the card token, the masked card number, the card type and the expiry date. It does not carry the 3D Secure result. The result is stored on the token.
The full list of form parameters is on Request Card Entry Form, and the full list of messages is on postMessage Notifications.

The Server

The server does two things: it starts a temporary session for the card entry form, and it charges the token. Your API key is read from an environment variable.
To run the Node.js version, put checkout.html and card-failed.html in a public folder, install Express with npm install express, set PCI_BOOKING_API_KEY to your sandbox API key, and run node server.js. Because postMessageHost must match your page’s origin, open the page through the server, not as a local file.

Moving From the Test Gateway to Your PSP

When the flow works with NULLSuccess, switch to your own PSP:
  1. Store your PSP credentials in PCI Booking, see Gateway Credentials.
  2. In the charge request, remove the PaymentGateway object and add ?credentialsId=YOUR_CREDENTIALS_ID to the URL.
  3. Read the gateway-specific guidance for your PSP. Some PSPs need extra fields, such as more PayerDetails.
Use your PSP’s test credentials with your PCI Booking sandbox account, and your PSP’s live credentials with your PCI Booking live account. If they do not match, the PSP rejects the request.

Making Sure the Card Has 3D Secure

This example sets UnavailThreeDSAuth=Reject. If the card cannot complete 3D Secure, for example because the card is not enrolled, it is not tokenized: the cardholder sees your failure page and your page gets CardSubmitFailure. With the default, Accept, the card is stored without 3D Secure data, and a PSP that requires 3D Secure will then decline the charge. A card that fails the 3D Secure challenge is always rejected, whatever the value of UnavailThreeDSAuth.

Troubleshooting