Get started
Last updated: December 19, 2022
Learn how to embed a form in your website or application to accept payments from your customers. We'll walk you through a payment flow using our Frames product, which collects card details through an iframe. The information is sent directly to us, so it never touches your server, and you remain PCI-compliant.
In this guide, we combine our Frames tokenization product with our core Unified Payments API. You can also take advantage of our end-to-end products, Hosted Payments Page and Payment Links, while retaining the same level of PCI compliance.
You embed the Frames payment form into your website or application.
Your customer enters payment details through the payment form.
We receive your customer's sensitive information and return a token representing those details. This process is called tokenization.
You use the token to make a payment request.
You present the payment request to the customer.
Make sure you have an account with us. Once you've signed in, navigate to Developers > Keys and create your keys. You'll need a public key to use Frames, and a way to authenticate your payment request. We support OAuth 2.0 and secret keys as authentication mechanisms.
The Frames payment flow requires both a client-side and a server-side.
- Client-side: Reference the Frames script and define where the payment form is displayed.
- Server-side: Securely send the payment request using your server.
If you use this template, you must set up your own server.
1<!DOCTYPE html>2<html lang="en">3 <head>4 <meta charset="utf-8" />5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />6 <title>Checkout Frames v2: Single Frame</title>7 <link rel="stylesheet" href="normalize.css" />8 <link rel="stylesheet" href="style.css" />9 </head>10
11 <body>12 <form13 id="payment-form"14 method="POST"15 action="https://merchant.com/charge-card"16 >17 <div class="one-liner">18 <div class="card-frame"></div>19 <button id="pay-button" disabled>PAY GBP 24.99</button>20 </div>21 <p class="error-message"></p>22 <p class="success-payment-message"></p>23 </form>24
25 <script src="https://cdn.checkout.com/js/framesv2.min.js"></script>26 <script src="app.js"></script>27 </body>28</html>
Add the script to your project in your index.html
file.
1<script src="https://cdn.checkout.com/js/framesv2.min.js"></script>
If you use server-side rendering (using your backend), using a framework like Next.js, you can add the script in the head
component.
1<head>2 <script src="https://cdn.checkout.com/js/framesv2.min.js"></script>3</head>
To remain PCI-compliant, payment details must be sent directly to us without interacting with your server. Always load framesv2.min.js
from cdn.checkout.com
. Do not host the script yourself.
Add the code for your payment form in your html
file. The amount on the payment button has been hard coded for this example.
The Frames script looks for an empty div
tag to insert an iframe containing the payment form. If you do not include div
tags, the payment form will not be visible in your website or application.
1<form id="payment-form" method="POST" action="https://merchant.com/charge-card">2 <div class="one-liner">3 <div class="card-frame">4 <!-- Frames will be added here -->5 </div>6 <button id="pay-button" disabled>PAY GBP 24.99</button>7 </div>8 <p class="error-message"></p>9 <p class="success-payment-message"></p>10</form>
In your js
file, you need to initialize Frames using your public key. Without this, the iframe will not appear in your website or application.
In our example, we use the init
method on the Frames
object, which we accessed from the Frames script.
1Frames.init("pk_sbox_XXXX");
Now that Frames is loaded in your website or application, we can use it to tokenize card details.
In your js
file, add the example code. This tells Frames to submit the card details and begin the tokenization process.
1var form = document.getElementById("payment-form");2
3form.addEventListener("submit", function (event) {4 event.preventDefault();5 Frames.submitCard();6});
Use the Frames.Events.CARD_TOKENIZED
event to listen for when details have successfully been tokenized. When this event is triggered, you can access the token value through event.token
.
The value returned is the token you need to use to request your payment, so make a note. Tokens begin with tok_
. For our example, you can simply copy the token that appears in the example iframe.
1Frames.addEventHandler(Frames.Events.CARD_TOKENIZED, (event) => {2 console.log(event.token);3});
Use these test card details using either the interactive iframe on this webpage, or on your local machine:
Card Number: | 4242424242424242 |
---|---|
Expiry Date: | Any date in the future |
CVV: | 100 |
If you are testing on your local machine, you will likely only be able to test with Visa, Mastercard and American Express card numbers. If you try and use a test card number for a different scheme, the tokenization will fail and the CARD_TOKENIZATION_FAILED
handler will be called.
When you select the Buy now button in this example iframe, we show you the token underneath the payment form. This is for demonstration purposes only and does not reflect what your customer will see.
You need to send the token to your server, so your server has access to it when you request the payment.
Send the token either with the form action when we submit our card details, or with a simple HTTPS post request.
We are now working in your server. Because you have a token that simply represents card details, you can handle it on your own server and remain PCI-compliant.
When payment details are tokenized, the token can only be used once and within 15 minutes. If you request a payment using an expired token, the payment will fail.
View our API Reference for authentication guidance, and a complete reference of optional and required fields.
post
https://api.sandbox.checkout.com/payments
In the source
object:
type
should have the valuetoken
.token
should have your stored token as the value.
1{2 "source": {3 "type": "token",4 "token": "tok_XXX"5 },6 "amount": 2499,7 "currency": "USD",8 "processing_channel_id": "pc_XXX"9}
1<?php2
3require '../vendor/autoload.php';4
5use Checkout\CheckoutApiException;6use Checkout\CheckoutException;7use Checkout\CheckoutSdk;8use Checkout\Common\Currency;9use Checkout\Environment;10use Checkout\Payments\Request\PaymentRequest;11use Checkout\Payments\Request\Source\RequestTokenSource;12use Monolog\Handler\StreamHandler;13use Monolog\Logger;14
15$log = new Logger("checkout-sdk-php-sample");16$log->pushHandler(new StreamHandler("php://stdout"));17
18// Initialize Checkout API19try {20 $api = CheckoutSdk::builder()->staticKeys()21 ->environment(Environment::sandbox())22 ->secretKey(getenv("sk_sbox_XXX"))23 ->build();24} catch (CheckoutException $e) {25 $log->error("An exception occurred while initializing Checkout SDK : {$e->getMessage()}");26 http_response_code(400);27}28
29$postData = file_get_contents("php://input");30$request = json_decode($postData);31
32// The token generated by Frames on the client side33$requestTokenSource = new RequestTokenSource();34$requestTokenSource->token = $request->token;35
36$request = new PaymentRequest();37$request->source = $requestTokenSource;38$request->currency = Currency::$GBP;39$request->amount = 2499;40$request->processing_channel_id = "pc_XXX";41
42try {43 echo json_encode($api->getPaymentsClient()->requestPayment($request));44} catch (CheckoutApiException $e) {45 $log->error("An exception occurred while processing payment request");46 http_response_code(400);47}
That's it! You've just built your first payment flow with Checkout.com. Continue reading to find out more about different responses and next steps.
If you receive a 201 Success response with approved
set to true
, your request was successful.
1{2 "id": "pay_qzpz6fv4dv2etnarerhvqxsvlm",3 "action_id": "act_agaoqbtsccie5j2zd6jwdodpg4",4 "amount": 2499,5 "currency": "USD",6 "approved": true,7 "status": "Authorized",8 "auth_code": "631973",9 "response_code": "10000",10 "response_summary": "Approved",11 "balances": {12 "total_authorized": 2499,13 "total_voided": 0,14 "available_to_void": 2499,15 "total_captured": 0,16 "available_to_capture": 2499,17 "total_refunded": 0,18 "available_to_refund": 019 },20 "risk": {21 "flagged": false22 },23 "source": {24 "id": "src_usxsfdifd2pebamd734fwsihg4",25 "type": "card",26 "phone": {},27 "expiry_month": 1,28 "expiry_year": 2027,29 "scheme": "Visa",30 "last4": "4242",31 "fingerprint": "2FE6B057E42927009AA100493441AD7C8E88A82573FCAE69C02D8C919F017895",32 "bin": "424242",33 "card_type": "CREDIT",34 "card_category": "CONSUMER",35 "issuer_country": "GB",36 "product_id": "F",37 "product_type": "Visa Classic",38 "avs_check": "G",39 "cvv_check": "Y",40 "payment_account_reference": "V001763436387291028"41 },42 "processed_on": "2022-10-20T13:28:05.5201442Z",43 "scheme_id": "581305702984089",44 "processing": {45 "acquirer_transaction_id": "541740228271589217340",46 "retrieval_reference_number": "462197862661"47 },48 "expires_on": "2022-11-19T13:28:05.5201442Z",49 "_links": {50 "self": {51 "href": "https://api.sandbox.checkout.com/payments/pay_qzpz6fv4dv2etnarerhvqxsvlm"52 },53 "actions": {54 "href": "https://api.sandbox.checkout.com/payments/pay_qzpz6fv4dv2etnarerhvqxsvlm/actions"55 },56 "capture": {57 "href": "https://api.sandbox.checkout.com/payments/pay_qzpz6fv4dv2etnarerhvqxsvlm/captures"58 },59 "void": {60 "href": "https://api.sandbox.checkout.com/payments/pay_qzpz6fv4dv2etnarerhvqxsvlm/voids"61 }62 }63}