# Dojo Online Payments Documentation > Guides for accepting online payments with Dojo — prebuilt checkout page, payment components, payment links, and virtual terminal. API quick reference: - **API base URL**: https://api.dojo.tech - **Environment selection**: Sandbox and production both use `https://api.dojo.tech`; the API key determines which environment receives the request - **Authentication**: `Authorization: Basic ` (literal `Basic ` prefix; do not base64-encode `api_key:`) - **Version header**: `version: 2026-02-27` This file focuses on checkout and client-facing flows. Server-side payment lifecycle operations still use the Dojo API. Machine-readable specs: - [Dojo API v3](https://docs.dojo.tech/api/v3/bundled.json) - [Payments API (legacy)](https://docs.dojo.tech/payments/bundled.json) For complete online integration, also load: - `llms-payment-intents.txt` — payment lifecycle, webhooks, refunds, and saved-card flows This file contains all documentation content in a single document following the llmstxt.org standard. ## API keys >Learn how to manage your API keys. The Dojo API uses [Basic HTTP authentication](https://datatracker.ietf.org/doc/html/rfc7617). To authenticate requests you'll need to provide your API key. Use the [Developer Portal](https://docs.dojo.tech/development-resources/portal/#api-keys) to create a key or manage an existing key. ## Key format Keys are structured in a way that has semantic meaning: * They start with the prefix `sk_` (standing for security key). * After that, they contain the environment prefix, which is either: `sandbox_` or `prod_`. * Finally, the key content comes after that. Here is an example test key: `sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ`. ## How to use API keys You must include your secret API key in the authorization header of all requests, for example: ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Version: 2024-02-05' \ --data '{ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order-0001", "paymentMethods": [ "Card", "Wallet" ] }' ``` API requests without authentication will fail. ## Create a new key You can use a new API key as soon as you generate it. An API key is location bound. If your company account has different [location accounts](https://docs.dojo.tech/development-resources/portal#account-structure), make sure you have selected the correct one before generating the key. ## Delete a key You may delete API keys at any time. A deleted key stops working immediately. Key deletion **cannot** be undone. To delete a key, click the three dots next to your secret key and choose **Delete key**. --- ## Learn more [![](https://docs.dojo.tech/images/dojo-icons/Planet.svg) **Developer Portal** Find out more about Dojo Developer Portal and how to use it.](portal) --- ## Best Practices Protecting your website from fraudulent activity like card slamming is essential for maintaining the security of your customers' data and ensuring compliance with payment regulations. This guide outlines common threats and actionable steps you can take to reduce risk. ## Preventing Card Slamming and Automated Abuse Card slamming, a form of card testing, involves attackers using scripts to rapidly submit stolen card details to a checkout form. These attacks often aim to find valid card numbers by testing hundreds or thousands in quick succession. Here are some measures to help block these attacks: ### Add CAPTCHA or Bot Detection To reduce the risk of automated abuse: - Add CAPTCHA to any page that triggers payment or card checks. - Enforce checks both client-side and server-side. - Combine CAPTCHA with rate-limiting (e.g. block after five failures per IP). - Monitor IPs and block suspicious sources. - Consider tools like reCAPTCHA (v2, v3, or Enterprise) for scoring-based risk analysis. - Adjust thresholds or switch to visible CAPTCHA if abuse continues. CAPTCHA is best used as a short-term barrier. It may affect conversions slightly, so consider removing it when no longer needed. ### Additional Tips - **Rate limit requests**: Throttle repeated attempts from the same IP address or device fingerprint. - **Review analytics and logs**: Monitor for unusual patterns or spikes in failed attempts to identify abuse early. --- ### Contact information For technical questions on integration, design or securing your setup, feel free to contact our support team or consult the API reference for further configuration options. --- ## Code samples > Working code samples to plug-and-play. Our code samples are up and ready to integrate with your web apps and mobile apps. We have a dedicated GitHub repository to help you: - Create your own Checkout page or use our [prebuilt](https://docs.dojo.tech/payments/accept-payments/online-payments/checkout-page) one. - Configure and use [Dojo components](https://docs.dojo.tech/payments/accept-payments/online-payments/components). - Build a checkout experience on [mobile devices](https://docs.dojo.tech/mobile-integration) and web environments. Choose from the following list of integrations to get started: --- ## Data types Dojo uses a coherent format for data such as currencies, amounts, and dates across all of our APIs. ## Currency and amount We use the [ISO 4217](https://www.iso.org/iso-4217-currency-codes.html) standard for defining currencies. For examples, USD for US dollars or GBP for Great British pounds. We express amounts in minor units. That means they're expressed in the smallest unit of currency. For example, a GBP value of 500 represents £5, and a GBP value of 50 represents £0.50 (fifty pence). ``` json { "value": 500, "currencyCode": "GBP" } ``` ## Date and time Dojo APIs express date and time according to the [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format standard with combined date, time and timezone expressed in UTC. For example, `2021-05-12T07:45:00Z` represents the 12th of May 2021 at 07:45:00. The exception to this is the `expiryDate` field, which accepts values in the MM/YY format. ``` json { "transactionDateTime": "2021-05-12T07:45:00Z", "expiryDate": "04/21" } ``` ## Country Dojo APIs describe country codes using the two-letter [ISO 3166–1–alpha–2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) standard. For example, GB for Great Britain. ``` json { "countryCode": "GB" } ``` --- ## Development resources >This section contains resources to help developers build integrations with the Dojo Payments API. [![](https://docs.dojo.tech/images/dojo-icons/Planet.svg) **Developer Portal** Find out more about Dojo Developer Portal and how you can use it.](/development-resources/portal) [![](https://docs.dojo.tech/images/dojo-icons/TerminalWindow.svg) **API reference** Learn about API and integrate with API endpoints.](/api) [![](https://docs.dojo.tech/images/dojo-icons/Key.svg) **API keys** Learn how to manage your API keys.](/development-resources/api-keys) [![](https://docs.dojo.tech/images/dojo-icons/AnchorSimple.svg) **Webhooks** Subscribe to events and get notifications.](/development-resources/webhooks) [![](https://docs.dojo.tech/images/dojo-icons/Cube.svg) **SDKs** Check our software development kits.](/development-resources/sdk) [![](https://docs.dojo.tech/images/dojo-icons/Paste.svg) **Test cards** Use the card details to test your integrations.](/development-resources/testing) [![](https://docs.dojo.tech/images/dojo-icons/Copy.svg) **Code samples** Clone sample integrations.](/development-resources/code-samples) [![](https://docs.dojo.tech/images/dojo-icons/Message.svg) **Stack Overflow** Find answers to practical questions.](https://stackoverflow.com/questions/tagged/dojo.tech) [![](https://docs.dojo.tech/images/dojo-icons/Headset.svg) **Need a hand?** Our support team is always happy to help with any questions you have.](https://support.dojo.tech/hc/en-gb) [![](https://docs.dojo.tech/images/dojo-icons/Email.svg) **Email Support** Contact our Partner Enablement team directly.](mailto:partnertech@dojo.tech) --- ## Legacy API keys >Still using Connect-E? Learn how to retrieve the JSON Web Token. > **Info:** Dojo highly recommends that you use the latest [Dojo API keys](https://docs.dojo.tech/development-resources/api-keys). Going forward, [JWT](https://jwt.io/introduction) tokens will become obsolete with limited support. > If you are using the old APIs to integrate Dojo as a payment method and want to retrieve the JWT token, do the following: 1. In the developer portal, click **Dojo app** and login. 2. In the sidebar, go to **Accounts** > **Locations**. 3. Select the location linked to your website. A **Location details** tab appears. 4. In the **Location details** tab, go to **REMOTE PAYMENTS** > **Developer resources**. Here you can find the JWT token and gateway username. ![JWT token](https://docs.dojo.tech/images/jwt-token.png) --- ## LLM-friendly docs > Use our LLM-friendly documentation to help AI coding assistants integrate with Dojo APIs. If you're using an AI coding assistant like **GitHub Copilot**, **Claude Code**, **Codex**, or similar tools, you can point them to our LLM-optimized documentation for faster, more accurate integration help. ## Available files | File | URL | Description | |------|-----|-------------| | **llms.txt** | [/llms.txt](https://docs.dojo.tech/llms.txt) | Index of all documentation with links — start here | | **llms-full.txt** | [/llms-full.txt](https://docs.dojo.tech/llms-full.txt) | All documentation in a single file | ### By integration type | File | URL | Description | |------|-----|-------------| | **llms-online.txt** | [/llms-online.txt](https://docs.dojo.tech/llms-online.txt) | Online payments — checkout, Components, payment links, and virtual terminal | | **llms-payment-intents.txt** | [/llms-payment-intents.txt](https://docs.dojo.tech/llms-payment-intents.txt) | Payment intents, setup intents, captures, refunds, cancellations, and webhooks | | **llms-inperson-pac.txt** | [/llms-inperson-pac.txt](https://docs.dojo.tech/llms-inperson-pac.txt) | Pay at Counter terminal sessions, captures, refunds, and pre-authorisation | | **llms-inperson-pat.txt** | [/llms-inperson-pat.txt](https://docs.dojo.tech/llms-inperson-pat.txt) | Pay at Table — searching payable orders, locking/unlocking, recording payments, and printable bills | | **llms-epos.txt** | [/llms-epos.txt](https://docs.dojo.tech/llms-epos.txt) | EPOS capability registration, event contracts, and EPOS Data API integration | | **llms-core-concepts.txt** | [/llms-core-concepts.txt](https://docs.dojo.tech/llms-core-concepts.txt) | Shared orders, parties, reservations, tables, areas, terminal sessions, and event vocabulary | | **llms-order-and-pay.txt** | [/llms-order-and-pay.txt](https://docs.dojo.tech/llms-order-and-pay.txt) | Self-service ordering and payment flows coordinated with POS capabilities | | **llms-plugins.txt** | [/llms-plugins.txt](https://docs.dojo.tech/llms-plugins.txt) | WooCommerce, Magento, OpenCart, and PrestaShop plugin setup and troubleshooting | | **llms-bookings.txt** | [/llms-bookings.txt](https://docs.dojo.tech/llms-bookings.txt) | Dojo Bookings / RMS reservations, parties, tables, and POS synchronization | | **llms-mobile-ios.txt** | [/llms-mobile-ios.txt](https://docs.dojo.tech/llms-mobile-ios.txt) | iOS SDK | | **llms-mobile-android.txt** | [/llms-mobile-android.txt](https://docs.dojo.tech/llms-mobile-android.txt) | Android SDK | | **llms-mobile-reactnative.txt** | [/llms-mobile-reactnative.txt](https://docs.dojo.tech/llms-mobile-reactnative.txt) | React Native SDK | | **llms-mobile-ttpoi.txt** | [/llms-mobile-ttpoi.txt](https://docs.dojo.tech/llms-mobile-ttpoi.txt) | Tap to Pay on iPhone | ### OpenAPI specifications For precise API integration, agents can fetch the machine-readable OpenAPI specs directly: - **Dojo API (latest)**: [/api/v3/bundled.json](https://docs.dojo.tech/api/v3/bundled.json) - **Transactions API**: [/transactions/bundled.json](https://docs.dojo.tech/transactions/bundled.json) - **EPOS Data API (REST)**: [/epos-data/bundled.json](https://docs.dojo.tech/epos-data/bundled.json) - **EPOS Data API (WebSocket)**: [/epos-data-asyncapi/bundled.yaml](https://docs.dojo.tech/epos-data-asyncapi/bundled.yaml) - **PCI API**: [/pci-api/bundled.json](https://docs.dojo.tech/pci-api/bundled.json) ## How to use ### GitHub Copilot (Copilot Chat / Copilot Coding Agent) Copy the relevant file URL from the tables above into a prompt like: ``` Fetch the llms-full.txt URL above and use it to help me integrate Dojo payments into my app. ``` ### Claude Code Use the `/fetch` command or point Claude to the file you need: ``` Fetch the llms-payment-intents.txt URL above and help me create a payment intent using the Dojo API. ``` ### OpenAI Codex / ChatGPT Paste the relevant file URL or its content into your prompt: ``` Using the llms.txt URL above, help me set up webhooks for payment notifications. ``` > **Tip:** For focused tasks, prefer the narrowest product-specific file, such as `llms-online.txt`, `llms-payment-intents.txt`, `llms-epos.txt`, `llms-plugins.txt`, or the relevant mobile SDK file, instead of the full documentation. > > > ## What's included > > These files follow the [llmstxt.org](https://llmstxt.org/) standard and are automatically generated from our documentation. They include: > > - All human-written guides and tutorials > - Links to OpenAPI specifications for all Dojo APIs > - Authentication details and API base URLs > - Code examples and step-by-step integration guides > > The files are regenerated with every documentation update, so they're always in sync with the latest docs. > > --- > > ## Developer Portal > > > Find out more about the Dojo Developer Portal and how you can use it. > > The Developer Portal contains a set of tools that developers can use to manage their integrations with our Dojo APIs, including API keys and WebHooks. > > **[Login to Dojo Developer Portal](https://developer.dojo.tech/login)** > > To get started using the Dojo Developer Portal, you'll first need a Dojo account. > If you don't have an account, [sign up now](https://account.dojo.tech/register?redirectLink=https:%2F%2Faccount.dojo.tech%2Flogin). > > ## Sandbox and production environments > > You can choose between two environments on the Developer Portal: > > * **Test mode** — This is a sandbox environment that allows you to safely test integrations before using them in production. In this mode, you don’t modify your live data. Use test mode to develop your integration. > > * **Live mode** — This is the production environment that gives you access to the real data. Use this mode when you’re ready to launch your integration. > > To switch between the two modes, use the toggle in the left menu. > > ![](https://docs.dojo.tech/images/test-mode.png) > > ## Account structure > > With Dojo, you have a single company account, and one or more sub-accounts called **location accounts**. > > * Company account — This represents your business entity with us, and holds all your location accounts. > > * Location accounts — This represent your unique point of sale, like a shop or café. > > Each location account has two keys: a secret key for the [sandbox environment](https://docs.dojo.tech/development-resources/llm-friendly-docs#sandbox-and-production-environments) and a secret key for the [production environment](https://docs.dojo.tech/development-resources/llm-friendly-docs#sandbox-and-production-environments). You can find your keys in the Developer Portal. Learn how to [manage your API keys](https://docs.dojo.tech/development-resources/api-keys). > > To view data related to a specific location account, select the drop-down menu in the top left and choose a location account. > > ![](https://docs.dojo.tech/images/account-menu.png) > > ## API keys > > You can create or manage [API keys](https://docs.dojo.tech/development-resources/api-keys) in the Developer Portal. > > If your company account has different [location accounts](https://docs.dojo.tech/development-resources/portal#account-structure), make sure you have selected the correct one before creating the key. > > When you first log in to the Developer Portal, you'll notice an API key already created, named **Initial API Key**. This key is provided for your convenience, so you don't need to generate one manually. It has access to the **Dojo API**, but is only enabled for the products your account is approved for. You can perform any API request related to those products, just like any key you generate yourself. > > If you want to use **Online Checkout**, go to the Developer Portal, select **Account activation** from the sidebar, and follow the instructions on the page. More information [here](https://support.dojo.tech/hc/en-gb/articles/5861747539996-The-Developer-Portal). > > ## WebHooks > > You can manage WebHooks in the Developer Portal, using the following instructions. You also can manage WebHooks directly, using our [API](https://docs.dojo.tech/development-resources/webhooks). > > ### Create a new webhook > > 1. Go to **Developer Portal** > **Webhooks** and select **+Add endpoint**. > > 2. Enter your endpoint URL and select the events you want to subscribe to. > > 3. Click **Add endpoint**. > > ### Edit, or delete an existing webhook > > To edit or delete a WebHook, click the three dots next it and select the relevant option. > > --- > > ## Learn more > > > > [![](https://docs.dojo.tech/images/dojo-icons/AnchorSimple.svg)**Set up notification webhooks** Use WebHooks to receive updates related to your payments.](webhooks) > > [![](https://docs.dojo.tech/images/dojo-icons/Key.svg)**Generate API keys** Learn how to manage your API keys.](api-keys) > > > > --- > > ## Test card numbers > > Use the information on this page to test your integration. > > Dojo issues physical point-of-sale test cards to test [in-person payments](https://docs.dojo.tech/payments/accept-payments/in-person-payments/introduction) integrations. > > Alternately, if you are testing [online payments](https://docs.dojo.tech/payments/accept-payments/online-payments/introduction) integrations, you can use the virtual test card values below: > > **Info:** The test card numbers are only valid for the Dojo sandbox environment. In order to test your site, use the test cards with your test [API key](https://docs.dojo.tech/development-resources/api-keys). Any address and cardholder name can be used with the test cards. --- ## Versioning The Dojo Payments API uses the YYYY-MM-DD API version scheme. The current `version` header must be passed as part of all API calls. When you make the first API request, using the current date in the `version` header will fetch the latest available version. ## Breaking changes Breaking or backwards-incompatible changes include: - Changing the URL format. - Changing parameters from non-mandatory to mandatory. - Changing the type of a parameter. - Changing authentication mechanism. - Adding new mandatory request parameters to existing API methods. - Removing or renaming a resource, field, method or an enum value. If we make breaking changes to the API, we release new, dated versions. We don't change your version, if you want to use a new version you have to change the version yourself. ## Non-breaking changes The following types of changes don't qualify as breaking changes, this list isn't exhaustive: - Adding new HTTP headers. - Adding new values to an enum if there is a default defined. - Adding new HTTP methods to existing resources. - Adding new non-mandatory request or response parameters to existing API methods. - Changing parameters from mandatory to non-mandatory. ## How to upgrade API When we release a new API version, you can choose to upgrade to gain access to new features. To change the API version you need to change the `version` header. When non-breaking changes are implemented into the current API version, these features will become available without needing an upgrade. --- ## Webhooks >Learn how to get notified of any changes in your payments' data. Webhooks allow your application to receive notifications when certain events occur. For example, when a payment status is updated, Dojo will make a POST request to your URL and let you know about it. You can create 1 webhook for each event. Use the [Webhooks API](https://docs.dojo.tech/api#tag/Webhooks) to specify which events you would like to be notified about. Every webhook from Dojo includes a `dojo-signature` header. You can use this to verify that the data is coming from Dojo. > **Tip:** Dojo sends this header as `Dojo-Signature`. Header names are case-insensitive by specification, but your server environment might expose them differently. Some frameworks or languages may automatically lowercase header names. Make sure to test and verify how headers are accessed in your environment to avoid integration issues. ## Response handling When handling server code webhook calls, Dojo does the following: - Accepts any `2xx` HTTP status code responses as a confirmation of successful delivery of the webhook message. - Interprets `4xx` or `5xx` HTTP status code responses as an error and re-attempts delivery for a limited number of times. ## Create webhooks Use the following instructions to create webhooks by using our API. You can also manage webhooks in the [Developer Portal](https://docs.dojo.tech/development-resources/portal#webhooks). To start using webhooks, you need: 1. [Choose which events to subscribe to](https://docs.dojo.tech/development-resources/webhooks#step-1-choose-which-events-to-subscribe-to). 2. [Enable the webhook using the webhook endpoint](https://docs.dojo.tech/development-resources/webhooks#step-2-enable-the-webhook). 3. [Verify Dojo webhooks](https://docs.dojo.tech/development-resources/webhooks#step-3-verify-dojo-webhooks). 4. [Go live](https://docs.dojo.tech/development-resources/webhooks#step-4-go-live). ### Before you start Before you begin, make sure you have followed the [Getting started guide](https://docs.dojo.tech/payments/getting-started) and get your API keys. Webhooks API use the same Basic Authentication as Dojo API. For the test environment, use your secret key with the prefix `sk_sandbox_`. ### Step 1. Choose which events to subscribe to You can have a list of all events by sending a `GET` request to Dojo's webhooks endpoints. ```GET /webhooks/events``` We recommend subscribing to the `payment_intent.status_updated` event to receive updates on changes in the status of your payment intents. For a complete list of available events and their payloads, see [Available webhooks](https://docs.dojo.tech/development-resources/webhooks#available-webhooks). ### Step 2. Enable the webhook You can turn on webhooks either via the developer portal (https://developer.dojo.tech) or using the APIs. To enable a webhook using the API, use the endpoint below: ``` POST /webhooks ``` In your request, include: * `events`: the list of events you would like to subscribe to. For the list of the events, see [Available webhooks](https://docs.dojo.tech/development-resources/webhooks#available-webhooks). * `url`: the endpoint the Dojo servers will send notifications to. The endpoint must be accessible from the public internet for the webhook to work. It must be an HTTPS endpoint as well. If you want to test webhooks before you create or configure a live service, you can use one of several request logging sites, for example, [WebHook Tester](https://webhook.site/). Alternatively, use a service like [ngrok](https://ngrok.com/). Here's an example of how to subscribe to the `payment_intent.status_updated` event: ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/webhooks \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Content-Type: application/json' \ --header 'Version: 2024-02-05' \ --data '{ "events": ["payment_intent.status_updated"], "url": "https://example.com/incoming-events" }' ``` For the full API specification, see the [API reference](https://docs.dojo.tech/api/#tag/Webhooks). ### Step 3. Verify Dojo webhooks To verify the authenticity of the webhook, you need to digest the received payload body by using [HMAC-SHA256](https://en.wikipedia.org/wiki/HMAC) with your `secret.value` as a key. If the result matches the one that you received in the `dojo-signature` header, then the webhook is authentic. For example: * for the following request body payload: :::warning In order to do a proper calculation, the JSON in the example below needs to be formatted without any spaces or line breaks. ``` json { "id": "evt_hnnHxIKR_Uy6bhZCusCltw", "event": "payment_intent.created", "accountId": "acc_test", "createdAt": "2022-02-01T13:07:41.8667859Z", "data": { "paymentIntentId": "pi_vpwd4ooAPEqyNAQe4z89WQ", "paymentStatus": "Created", "captureMode": "Auto" } } ```` * where the secret to calculate the signature was: `PDYkJQq6sESYHp_zJuTTBQ` * the signature header would be: `sha256=4B-49-F8-FE-25-A7-E6-7D-00-4F-A7-9C-F8-0B-63-00-C7-77-B4-F2-2D-E5-E1-22-84-FA-04-18-50-A1-76-FD` Below are examples in Python and C# to verify webhooks: ```py from hashlib import sha256 from flask import Flask, jsonify, request app = Flask(__name__) WEBHOOK_SECRET = "PDYkJQq6sESYHp_zJuTTBQ" def build_dojo_signature(payload: bytes, secret: str) -> str: digest = hmac.new( secret.encode("utf-8"), msg=payload, digestmod=sha256, ).digest() return "sha256=" + "-".join(f"{byte:02X}" for byte in digest) @app.route('/webhook', methods=['POST']) def webhook(): payload = request.get_data(cache=False) signature_header = request.headers.get('dojo-signature') if not signature_header: print('Missing dojo-signature header.') return jsonify(success=False), 400 expected_signature = build_dojo_signature(payload, WEBHOOK_SECRET) if not hmac.compare_digest(signature_header, expected_signature): print('Invalid signature.') return jsonify(success=False), 400 try: event = json.loads(payload.decode("utf-8")) except json.JSONDecodeError as error: print(f'Invalid webhook payload: {error}') return jsonify(success=False), 400 print('Signature verified.') print(json.dumps(event, indent=2)) return jsonify(success=True) ``` ### Step 4. Go live If you want to test webhooks before you create or configure a live service, you can use one of several request logging sites, for example, [WebHook Tester](https://webhook.site/). Alternatively, use a service like [ngrok](https://ngrok.com/). When you are ready to go live, switch your secret key to production one with the prefix `sk_prod_` and check `url` that you provide. ## Available webhooks ### Payment intents webhooks * `payment_intent.status_updated` * `payment_intent.created` * `payment_intent.send-receipt` | Property | Type |Description | |-----|-----|-----| |`id` |string|Unique identifier for the event.| |`event` |string|The event type. Possible values are `payment_intent.status_updated`, `payment_intent.created`, `payment_intent.send-receipt`.| |`accountId` |string|Unique identifier for the account. | |`createdAt` |string date-time|The timestamp of the create date, in [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) UTC format.| |`data` |object|Information regarding the payment.| |`data.paymentIntentId` |string|Unique identifier for the payment intent.| |`data.paymentStatus` |string|Current status of the payment intent. Possible values are `Created`, `Authorized`, `Captured`, `Reversed`, `Refunded`, `Canceled`.| |`data.captureMode` |string|The type of capture for the payment. Possible values are `Auto`, `Manual`.| ## Webhooks and events management You can manage webhooks and events by using our API: * [Retrieve a list of all events](https://docs.dojo.tech/api#operation/Webhooks_GetAllWebhooks). * [Retrieve a list of all subscriptions that you have](https://docs.dojo.tech/api#operation/Webhooks_GetAlSubscriptions). * [Create a new subscription for chosen events](https://docs.dojo.tech/api#operation/Webhooks_Subscribe). * [Update your subscription details](https://docs.dojo.tech/api#operation/Webhooks_SubscribeUpdate). * [Delete a subscription](https://docs.dojo.tech/api#operation/Webhooks_DeleteSubscriptions). * [Retrieve a list of secrets for the subscription](https://docs.dojo.tech/api#operation/Webhooks_GetSecrets). * [Generate a new secret](https://docs.dojo.tech/api#operation/Webhooks_GenerateSecret). * [Activate a secret](https://docs.dojo.tech/api#operation/Webhooks_ActivateSecret). * [Delete a secret](https://docs.dojo.tech/api#operation/Webhooks_DeleteSecret). --- ## Go-live checklist > Check off these steps before launching your integration in production. The following steps ensure you have a complete implementation. ## Test in the sandbox Before going live, test your integration in the [sandbox](https://docs.dojo.tech/development-resources/portal#sandbox-and-production-environments). For each payment method that you offer: * Make a successful payment. * Make an unsuccessful payment. Use the following test card numbers to make payments: ## Check the result Make your first live API call and check that your production key works. Open your checkout page to see the result. For the production environment, there should be no yellow **Sandbox** label. --- ## Prebuilt checkout page >Discover the Dojo Prebuilt Checkout. Dojo offers our own accessible, lightweight prebuilt checkout UI to simplify your payment implementations. It is fully secure, and has been designed to be as customizable and responsive as possible. ![Online checkout](https://docs.dojo.tech/images/online-checkout.jpg) ## What's in the box? - The prebuilt payment page, hosted by Dojo. - [Card payments and Wallet payments (Apple Pay and Google Pay)](https://docs.dojo.tech/payments/pay-at-table/checkout-page/configuration#add-payment-methods). - Validation of card details. - Email receipts. - Responsive design. - [Strong Customer Authentication (SCA)](https://www.fca.org.uk/firms/strong-customer-authentication). - [Address forms to collect customer details](https://docs.dojo.tech/payments/pay-at-table/checkout-page/configuration#collect-billing-address-shipping-details-and-customer-email). --- ## Let's get started [![Let's get started](https://docs.dojo.tech/images/dojo-icons/BookBookmark.svg) **Step-by-step guide** Learn how to implement a Checkout Page ready to accept payments.](checkout-page/step-by-step-guide) --- ## Optional configuration >Learn how to activate additional features for your checkout page. Additional configuration is a useful way to capture extra information about your customers, and you can set up whichever fields best meet the needs of your implementation. For example, a lot of merchants operate online stores and send things to their customers, so the shipping address is one of the most commonly-used optional fields. A billing address is required even more frequently, in cases where a transaction does not involve physical items. The following examples include the other most common optional configurable payment fields. See the [API reference](https://docs.dojo.tech/api) for the full list of configurable fields. - [Add payment methods](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#add-payment-methods) Integrate Apple Pay and Google Pay wallets in addition to card payments. - [Collect billing address, shipping details, and customer email](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#collect-billing-address-shipping-details-and-customer-email) Use your checkout page to capture useful information about your customer. - [Redirect to your success page](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#redirect-to-your-success-page) Show your success page to customers. - [Show detailed information about the order and taxes](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#show-detailed-information-about-the-order-and-taxes) Set up the information that you want to show to customers. - [Add information about your company](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#add-information-about-your-company) Customize the checkout page title. ## Add payment methods ![](https://docs.dojo.tech/images/add-payment-methods.png) By default, the checkout page supports only card payments. To enable Apple Pay and Google Pay wallets, pass `"Card","Wallet"` in `paymentMethods`, for example: ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Version: 2024-02-05' \ --data '{ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order-0001", "paymentMethods": [ "Card", "Wallet" ] }' ``` You must [verify your domain](https://developer.apple.com/documentation/applepaywebmerchantregistrationapi/preparing_merchant_domains_for_verification) for Apple Pay. ## Collect billing address, shipping details, and customer email ![](https://docs.dojo.tech/images/billing-and-shipping-details.png) You can add a form to collect billing address, shipping details, and the customer email to the checkout page, by passing `collectionRequired: true` in `config.billingAddress`, `config.shippingDetails`, and `config.customerEmail`: ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Version: 2024-02-05' \ --data '{ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order-0001", "config": { "customerEmail": { "collectionRequired": true }, "billingAddress": { "collectionRequired": true }, "shippingDetails": { "collectionRequired": true } } }' ``` ## Redirect to your success page After your customer submits payment information on the checkout page, Dojo processes the payment and redirects the customer to the success page. You can, alternately, redirect the customer to another page of your choice after payment, by passing the URL in `config.redirectUrl`: ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Version: 2024-02-05' \ --data '{ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order-0001", "config": { "redirectUrl": "http://mymerchantsite.com/checkout/success_pay" } }' ``` ## Show detailed information about the order and taxes ![](https://docs.dojo.tech/images/show-detailed-information.png) You can add information about each position in the order to the checkout page, to do it, pass this data to `itemLines`. Additionally, you can add information about any taxes or fees included in the order using `taxLines`. Item and tax amounts do not affect the payment intent amount. To add total due to the checkout page, pass `showTotal: true` in `config.details`. This value will be the same as the [payment intent](https://docs.dojo.tech/manage-payments/payment-intent) amount. ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Version: 2024-02-05' \ --data '{ "amount": { "value": 1510, "currencyCode": "GBP" }, "reference": "Order-0001", "itemLines": [ { "id": "item 1", "quantity": 4, "caption": "Dog socks", "amountTotal": { "value": 400, "currencyCode": "GBP" } }, { "id": "item 5", "quantity": 1, "caption": "Dog bandana", "amountTotal": { "value": 600, "currencyCode": "GBP" } } ], "taxLines": [ { "id": "vat", "caption": "VAT", "subCaption": "10%", "amountTotal": { "value": 10, "currencyCode": "GBP" } }, { "id": "delivery", "caption": "Delivery", "amountTotal": { "value": 500, "currencyCode": "GBP" } } ], "config": { "details": { "showTotal": true } } }' ``` ## Add information about your company ![](https://docs.dojo.tech/images/show-title.png) You can customize the checkout page’s title, for example, by adding your company name. To do this, pass a title in `config.title`. If you leave this parameter empty it will default to the trading name you provided to Dojo at sign-up. ```bash # The sandbox API key passed in 'authorization' is public. # Don't submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'Content-Type: application/json' \ --header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'Version: 2024-02-05' \ --data '{ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order-0001", "config": { "title": "The Company" } }' ``` --- ## More information [![](https://docs.dojo.tech/images/dojo-icons/TickCircle.svg) **Check your integration** Check off these steps before launching your integration in production.](checklist) [![](https://docs.dojo.tech/images/dojo-icons/TerminalWindow.svg) **API reference** See the API reference for a complete list of parameters you use.](/api) --- ## Customization >Learn about customizing your prebuilt checkout page. You can customize how your prebuilt checkout page looks by adding your logo. ## Ready to get started? [![](https://docs.dojo.tech/images/dojo-icons/Wrench.svg) **Add your logo** Customize your payment page to add your own logo.](https://support.dojo.tech/hc/en-gb/articles/5235120320924-Add-your-logo-to-your-payment-links) --- ## Step-by-step guide >Learn how to implement our Checkout Page to accept payments. A checkout page integration contains the following: - Server-side: one API request to create a payment intent. - Client-side: a redirect to the Checkout Page. - WebHooks: a server-side endpoint to receive information about the payment. The payment flow is: 1. The customer visits the merchant's site and clicks the Checkout button. 2. The merchant client-side sends the customer's purchases information to the merchant server-side, and the merchant server-side sends this information to the Dojo server and [creates a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-create-a-payment-intent). 3. The merchant client-side [redirects the customer](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-2-redirect-your-customer-to-dojo-checkout-page) to the Prebuilt Checkout Page, which is hosted by Dojo. 4. The Prebuilt Checkout Page collects the customer's payment details, sends them to the Dojo servers, and redirects the customer to the results page. 5. The merchant server receives a [WebHook notification](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-handle-post-payment-events) when the payment is completed. ![](https://docs.dojo.tech/images/flow-checkout-page.jpg) **Flow diagram: Flow Checkout Page** ```mermaid sequenceDiagram actor C as Customer participant DC as dojo Client-side participant MC as Merchant Client-side participant MS as Merchant Server-side participant DS as dojo Server-side C->>MC: Clicks "Checkout" MC->>MS: Sends information about customer purchases MS->>DS: POST /payment-intents DS-->>MS: PaymentIntent object MS-->>MC: PaymentIntentId MC->>DC: Redirects to Prebuilt Checkout Page C->>DC: Enters payment details and clicks "Pay" DS-->>DC: Redirects to the result page DS->>MS: Sends webhooks ``` **LLM walkthrough: complete Checkout Page happy path** Use this template when your server creates the payment intent and the browser only needs to redirect the customer to Dojo Checkout. All Dojo REST calls in this walkthrough use: - `Authorization: Basic ` (literal `Basic ` prefix; do not base64-encode `api_key:`) - `version: 2026-02-27` - `Content-Type: application/json` **1. Create the payment intent with a redirect URL** **POST** `/payment-intents` **Request body** ```json { "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order-0001", "description": "Hosted checkout payment for basket 245", "config": { "redirectUrl": "https://merchant.example/checkout/success" } } ``` **Response body** ```json { "id": "pi_sandbox_G_FeegU8WESxtY_Nct8jqw", "captureMode": "Auto", "status": "Created", "paymentMethods": [ "Card" ], "amount": { "value": 1000, "currencyCode": "GBP" }, "totalAmount": { "value": 1000, "currencyCode": "GBP" }, "refundedAmount": 0, "createdAt": "2024-04-07T23:25:44.802258Z", "updatedAt": "2024-04-07T23:25:44.802258Z", "reference": "Order-0001", "description": "Hosted checkout payment for basket 245", "paymentLink": "https://pay.dojo.tech/checkout/pi_sandbox_G_FeegU8WESxtY_Nct8jqw", "paymentEvents": [], "terminalSessionHistory": [] } ``` **2. Return the checkout URL to the browser and redirect the customer** Your own backend can return the payment link it received from Dojo: ```json { "paymentIntentId": "pi_sandbox_G_FeegU8WESxtY_Nct8jqw", "paymentLink": "https://pay.dojo.tech/checkout/pi_sandbox_G_FeegU8WESxtY_Nct8jqw" } ``` Then redirect the browser to `paymentLink`: ```js window.location.replace("https://pay.dojo.tech/checkout/pi_sandbox_G_FeegU8WESxtY_Nct8jqw"); ``` **3. Handle the success page by fetching the latest payment status** When the browser lands on your `redirectUrl`, load the `paymentIntentId` you stored for the checkout session and call Dojo from your backend to render the latest status on the page. **GET** `/payment-intents/pi_sandbox_G_FeegU8WESxtY_Nct8jqw` **Response body** ```json { "id": "pi_sandbox_G_FeegU8WESxtY_Nct8jqw", "captureMode": "Auto", "status": "Captured", "paymentMethods": [ "Card" ], "amount": { "value": 1000, "currencyCode": "GBP" }, "totalAmount": { "value": 1000, "currencyCode": "GBP" }, "refundedAmount": 0, "reference": "Order-0001", "description": "Hosted checkout payment for basket 245", "paymentDetails": { "transactionId": "19e4535e-ef6e-48e2-90be-d2b313c1cefd", "transactionDateTime": "2024-07-25T08:49:20.973410318Z", "message": "DEPOSITED", "authCode": "123456", "card": { "cardNumber": "44565300****1096", "cardName": "test", "expiryDate": "2024-12-31", "cardType": "VISA", "entryMode": "Contactless", "verificationMethod": "Pin" } }, "paymentEvents": [ { "transactionId": "19e4535e-ef6e-48e2-90be-d2b313c1cefd", "transactionDateTime": "2024-07-25T08:49:20.973410318Z", "eventType": "Captured", "authCode": "123456", "cardNumber": "44565300****1096", "expiryDate": "2024-12-31", "cardType": "VISA", "cardholderName": "test", "paymentMethodId": "" } ] } ``` Use the success page for customer UX only. Treat the webhook as the final source of truth for order fulfilment. **4. Subscribe to and verify the webhook notification** **POST** `/webhooks` **Request body** ```json { "events": [ "payment_intent.status_updated" ], "url": "https://merchant.example/webhooks/dojo" } ``` **Response body** ```json { "id": "ws_aNkU6yob0vOMxUlghg2oynUw", "accountId": "acc_4z3k2xP17e1JQY", "events": [ "payment_intent.created", "payment_intent.status_updated" ], "url": "https://merchant.example/webhooks/dojo", "description": "Demo Webhooks", "secrets": [ { "id": "sc_qNkU6yob0vOMxUlb2oynUw", "value": "U3Vic2NyaXB0aW9uUmVzcG9uc2VFeGFtcGxlIDogSUV4YW1wbGVQcm92aWRlcjxTdWJ", "createdAt": "2023-12-13T14:15:01", "lastUsedAt": "2023-12-16T13:44:03.3242202Z", "isActive": true } ], "createdAt": "2023-03-30T12:21:04.143Z", "updatedAt": "2023-03-30T12:21:04.143Z" } ``` **Incoming webhook payload** ```json { "id": "evt_hnnHxIKR_Uy6bhZCusCltw", "event": "payment_intent.status_updated", "accountId": "acc_test", "createdAt": "2024-07-25T08:49:24.761Z", "data": { "paymentIntentId": "pi_sandbox_G_FeegU8WESxtY_Nct8jqw", "paymentStatus": "Captured", "captureMode": "Auto" } } ``` ## How to process a payment Step-by-step guide: 1. [Create a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-create-a-payment-intent). 2. [Redirect your customer to the Dojo Checkout Page](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-2-redirect-your-customer-to-dojo-checkout-page). 3. [Handle post-payment events](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-handle-post-payment-events). 4. [Test and go live](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-4-test-and-go-live). ### Before you start ### Step 1. Create a payment intent To create a payment intent, the following parameters are required: - `amount`: This includes the currency and value, in minor units, for example, "1000" for 10.00 GBP. - `reference`: Your unique reference for the payment intent. Here's an example of how to create a payment intent for 10 GBP on your server-side: ```py title="server.py" @app.route('/checkout', methods=['GET', 'POST']) def hello(): # POST request if request.method == 'POST': print(request.get_json()) # parse as JSON conn = http.client.HTTPSConnection("api.dojo.tech") # call post payment-intent payload = json.dumps({ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order 245" }) headers = { 'Content-Type': "application/json", 'Version': "2024-02-05", 'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ" # <-- Change to your secret key } conn.request("POST", "/payment-intents/", payload, headers) # handling the response from POST res = conn.getresponse() data = res.read() resp_data = {} resp_data['id'] = json.loads(data)["id"] json_data = json.dumps(resp_data) resp = app.response_class( response=json_data, mimetype='application/json' ) return resp ``` See the [API reference](https://docs.dojo.tech/api#operation/PaymentIntents_CreatePaymentIntent) for a complete list of parameters that can be used for payment intent creation. ### Step 2. Redirect your customer to Dojo Checkout Page After receiving the request, Dojo creates a payment intent and returns its unique ID: ```json { "id": "pi_CggWPWfehUWgVNnDdsdLMQ", ... } ``` Return this ID to the client-side and use it to create a link in the following format: `https://pay.dojo.tech/checkout/{{id}}` Redirect your customer to the link on your client-side: ```js title="online-checkout-client.html" .then(response => response.json()) .then(function (data) { var redirectLink = "https://pay.dojo.tech/checkout/" + data.id window.location.replace(redirectLink) }); ``` After your customer fills payment information on the checkout page, Dojo processes the payment and redirects the customer to the success page. ### Step 3. Handle post-payment events ### Step 4. Test and go live Before going live, test your integration using the test card numbers: --- ## Next steps [![](https://docs.dojo.tech/images/dojo-icons/AnchorSimple.svg) **Set up notification webhooks** Use webhooks to receive updates related to your payments.](/development-resources/webhooks) [![](https://docs.dojo.tech/images/dojo-icons/Settings.svg) **Configure Checkout Page** Find out how to add another payment method or shipping address form to the page.](configuration) [![](https://docs.dojo.tech/images/dojo-icons/TickCircle.svg) **Check your integration** Check off these steps before launching your integration in production.](checklist) [![](https://docs.dojo.tech/images/dojo-icons/Filters.svg) **Manage payments** Learn how to capture or reverse payments, retrieve payment details or change payments amount.](../../../manage-payments) --- ## Card >Learn how you can embed the prebuilt Dojo Card Component into your checkout page. The Dojo Card Component is a prebuilt JavaScript component for accepting payments on your checkout page. Use this integration option when you want full control over the payment flow and the look of your checkout page. In terms of implementation, the integration contains: - Server-side: one API request to create a payment intent. - Client-side: set up Dojo Card Component, which securely sends payment data to our server. - Webhooks: server-side endpoint to receive information about the payment. The payment flow is: 1. The customer visits the merchant's site and clicks the Checkout button. 2. The merchant client-side sends the customer's purchase information to the merchant server-side, and the merchant server-side sends this information to Dojo server to [create a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-create-a-payment-intent). 3. The merchant client-side creates an instance of the [card component](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-add-the-component-to-your-checkout-page) using the `clientSessionSecret`. 4. The customer enters payment details directly on the merchant checkout page to the card component. 5. The card component collects the customer's payment details, sends them to the Dojo servers, and redirects the customer to the result page. 6. The merchant server receives a [webhook notification](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-4-handle-post-payment-events) when the payment is completed. ![](https://docs.dojo.tech/images/flow-card.jpg) **Flow diagram: Flow Card** ```mermaid sequenceDiagram actor C as Customer participant MC as Merchant Client-side participant MS as Merchant Server-side participant D as dojo C->>MC: Clicks "Checkout" MC->>MS: Sends information about customer purchases MS->>D: POST /payment-intents D-->>MS: PaymentIntent object MS-->>MC: Returns clientSessionSecret C->>MC: Enters payment details and clicks "Pay" MC->>D: D-->>MC: Redirects to the result page D->>MS: Sends webhooks ``` > **Info:** If you’re looking for a low-code option, take a look at our [pre-built checkout](https://docs.dojo.tech/payments/checkout-page). > ## How to process a payment Step-by-step guide: 1. [Add the component to your checkout page](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-add-the-component-to-your-checkout-page). 2. [Set up Dojo Card Component](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-2-set-up-dojo-card-component). 3. [Create a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-create-a-payment-intent). 4. [Handle post-payment events](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-4-handle-post-payment-events). 5. [Test and go live](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-5-test-and-go-live). ### Before you start ### Step 1. Add the component to your checkout page Include Dojo `client.js` script on your checkout page. This script must always load directly from `cdn.dojo.tech` to remain PCI compliant—you can’t include it in a bundle or host a copy of it yourself. ```html title="index.html" ``` Add empty placeholders div to your checkout page to create a payment form. For example: ```html title="index.html" Card component Payment Complete
Status Code
Auth Code
``` ### Step 2. Set up Dojo card component Next, in your JavaScript file, create an instance of Dojo: ```js title="script.js" .then(response => response.json()) .then(function (data) { const config = { paymentDetails: { paymentToken: data.clientSessionSecret, }, containerId: "demo-payment", fontCss: ['https://fonts.googleapis.com/css?family=Do+Hyeon'], styles: { base: {}, } } // intialising connection const card = new Dojo.Payment(config, displayErrorsCallback); // sending payment on button click and processing the response const btnTestPay = document.getElementById("testPay"); btnTestPay.onclick = () => { btnTestPay.innerText = 'loading'; btnTestPay.setAttribute("disabled", "true"); card.executePayment() .then(function (data) { document.getElementById("demo-payment").hidden = true; btnTestPay.remove(); document.getElementById("demo-result").hidden = false; document.getElementById("status-code").innerText = data.statusCode; document.getElementById("auth-code").innerText = data.authCode; }).catch(function (data) { console.log('Payment Request failed: ' + data); btnTestPay.innerText = 'Pay'; btnTestPay.removeAttribute("disabled"); if (typeof data === 'string') { document.getElementById("errors").innerText = data; } if (data && data.message) { document.getElementById("errors").innerText = data.message; } } ); }; ``` You can add an optional callback to display validation errors, such as invalid CVV or card number: ```js title="script.js" function displayErrorsCallback(errors) { const errorsDiv = document.getElementById('errors'); errorsDiv.innerHTML = ''; if (errors && errors.length) { const list = document.createElement("ul"); for (const error of errors) { const item = document.createElement("li"); item.innerText = error.message; list.appendChild(item); } errorsDiv.appendChild(list); } } ``` See the [Optional configuration](https://docs.dojo.tech/payments/pay-at-table/configuration) for a complete list of parameters that you can use. ### Step 3. Create a payment intent Call a server-side endpoint to create a payment intent, for example: ```js title="script.js" fetch('/checkout', { // Declare what type of data we're sending headers: { 'Content-Type': 'application/json' }, // Specify the method method: 'POST', mode: 'no-cors', // A JSON payload body: JSON.stringify({ "greeting": "" }) }) ``` To create a payment intent, the following parameters are required: - `amount`: This includes the currency and value, in minor units, for example, "1000" for 10.00 GBP. - `reference`: Your unique reference for the payment intent. - `paymentMethods: "Card"`: The payment method that customers can use to pay. Here's an example of how to create a payment intent on your server-side: ```py title="server.py" payload = json.dumps({ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order 245", "paymentMethods": ["Card"] }) headers = { 'Content-Type': "application/json", 'Version': "2024-02-05", 'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ" # <-- Change to your secret key } conn.request("POST", "/payment-intents/", payload, headers) # handling the response from POST res = conn.getresponse() data = res.read() resp_data = {} resp_data['clientSessionSecret'] = json.loads(data)["clientSessionSecret"] print(resp_data) json_data = json.dumps(resp_data) resp = app.response_class( response=json_data, mimetype='application/json' ) return resp ``` See the [API reference](https://docs.dojo.tech/api#operation/PaymentIntents_CreatePaymentIntent) for a complete list parameters that you can use. ### Step 4. Handle post-payment events ### Step 5. Test and go live Before going live, test your integration using the test card numbers: --- ## Next steps [![](https://docs.dojo.tech/images/dojo-icons/AnchorSimple.svg) **Set up notification webhooks** Use webhooks to receive updates related to your payments.](../../../../development-resources/webhooks) [![](https://docs.dojo.tech/images/dojo-icons/Settings.svg) **Configure Dojo Components** Find out how you can configure the Dojo Components.](./configuration) [![](https://docs.dojo.tech/images/dojo-icons/TickCircle.svg) **Check your integration** Check off these steps before launching your integration in production.](checklist) [![](https://docs.dojo.tech/images/dojo-icons/Filters.svg) **Manage payments** Learn how to capture or reverse payments, retrieve payment details or change payments amount.](../../../manage-payments) --- ## Go-live checklist(Components) > Check off these steps before launching your integration in production. The steps below will help to ensure you have a complete implementation. **Test in the sandbox** Before going live, test your integration in the [sandbox](https://docs.dojo.tech/development-resources/portal#sandbox-and-production-environments). For each payment method that you offer: * Make a successful payment. * Make an unsuccessful payment. * Make a successful payment after an unsuccessful one to test you [update a client session secret](https://docs.dojo.tech/api#tag/Payment-intents/operation/PaymentIntents_RefreshClientSessionSecret). * Make a successful payment with 3DS. * Make an unsuccessful payment with 3DS. Use the test card numbers below to make payments: **Update the client session secret** You need to [update the client session secret](https://docs.dojo.tech/api#tag/Payment-intents/operation/PaymentIntents_RefreshClientSessionSecret) every time you make any changes to the payment intent or the payment is declined. These tokens are **one-time use only**. If you need to retry a payment, you must generate a new token. Any changes to the payment intent amount invalidates the old client session secret and generates a new one. **Check the domain verification file** If you use the [wallet component](https://docs.dojo.tech/payments/pay-at-table/wallet) to enable Apple Pay, you must host the [domain verification file](https://cdn.dojo.tech/payments/assets/ApplePay/apple-developer-merchantid-domain-association) on each domain you want to use, including subdomains, under the following path: `https://yourdomain/.well-known/apple-developer-merchantid-domain-association`. Make sure that the file is downloadable and served at the correct location, as Apple will use this location to verify the validity of your domain. If your domain is protected from public access and you wish to complete domain verification, you should allow [Apple IP Addresses for Domain Verification](https://developer.apple.com/documentation/apple_pay_on_the_web/setting_up_your_server/#3179116). **Check the result** Make your first live API call to make sure that your production key is working. Open your checkout page to see the result. --- ## Dojo components >Learn how to use the Dojo Components for your online payments. Dojo Components are our ready-made JavaScript components that you can add to your website to accept payments. The components have error handling and input validation on the Client-side. > **Info:** If you’re looking for a low-code option, take a look at our [pre-built checkout](https://docs.dojo.tech/payments/accept-payments/online-payments/checkout-page). > ![](https://docs.dojo.tech/images/components.jpg) --- ## Ready to get started? [![](https://docs.dojo.tech/images/dojo-icons/PaymentCard.svg) **Card Component** Learn how to use our card component to accept payments.](/payments/accept-payments/online-payments/components/card) [![](https://docs.dojo.tech/images/dojo-icons/Wallet.svg) **Wallet Component** Learn how to use our single component for Apple Pay and Google Pay.](/payments/accept-payments/online-payments/components/wallet) --- ## Configure Dojo components ## Dojo Card ```js const card = new Dojo.Payment(config, displayErrorsCallback, onSubmitTriggered, onBlur); ``` | Parameter | Type | Description | |-------------------------|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `config` | object [Config](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#configuration) | Required. Config containing details of this payment and the styling of the payment form. | | `displayErrorsCallback` | function | An optional callback to display text [validation errors](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#validation-error). The supplied function is called when there is a validation state change. This function is passed an array of validationError objects. | | `onSubmitTriggered` | function | An optional callback that's called when the submit event on the payment form is fired. This allows the payment to be submitted or extra validation done when the user presses the enter key on the payment form. | | `onBlur` | function(isValid: boolean) | An optional callback that's called when focus is lost from any field in the form. The parameter isValid will be true when all fields are completed and there are no validation errors. | ## Dojo Wallet ```js const wallet = new Dojo.WalletPayment(config, displayErrorsCallback, paymentComplete); ``` | Parameter | Type | Description | |-----|-----|-----| |`config` |object [Config](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#configuration)|Required. Config containing details of this payment and the styling of the payment button. | |`displayErrorsCallback` |function| An optional callback to display text [validation errors](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#validation-error). The supplied function is called when there is a validation state change. This function is passed an array of validationError objects.| |`paymentComplete` | function|A callback that returns the result of payment. The supplied function is called when the payment is executed. This function is passed a [Transaction Result](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#transaction-result) object.| ## Configuration | Property | Type | Description | Card Component | Wallet Component | |---------------------------|----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------|----------------|------------------| | `containerId` | string | Required. The id of the div element where the payment details will be displayed. | ✓ | ✓ | | `paymentDetails` | [paymentDetails](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#payment-details) | Required. Details of the payment to be made. | ✓ | ✓ | | `fontCss` | array of strings | Array of urls pointing to css files for importing fonts, for example `https://fonts.googleapis.com/css?family=Do+Hyeon` | ✓ | - | | `styles` | [stylesConfig](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#styles-configuration) | Required. Object defining custom styles for the payment form. | ✓ | - | | `text` | [textConfig](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#text-configuration) | Object defining text to override the defaults. | ✓ | - | | `onIframeLoaded` | function | An optional function that's called once the iframe has been loaded and configured. | ✓ | ✓ | | `onIframeLoadFailed` | function | An optional function that's called if there is an error loading the iframe. | ✓ | ✓ | | `errorMessages` | [errorMessages](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#error-messages) | Object defining custom validation error messages for the payment form. | ✓ | ✓ | | `callbacks` | [callbacksConfig](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#card-callbacks) | Object defining callback functions on various events. | ✓ | - | | `callbacks` | [walletPaymentCallbacksConfig](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#wallet-callbacks) | Object defining callback functions on various events. | - | ✓ | | `buttonConfig` | [buttonConfig](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#button-configuration) | An optional button config. It defaults to colour black and type plain. | - | ✓ | | `emailRequired` | boolean | An optional config to collect the buyer's email. It defaults to false. | - | ✓ | | `billingAddressRequired` | boolean | An optional config to collect the buyer's billing address. It defaults to false. | - | ✓ | | `shippingAddressRequired` | boolean | An optional config to collect the buyer's shipping address. It defaults to false. | - | ✓ | ### Payment details | Property | Type | Description | |----------------|--------|------------------------------------------------------------------| | `paymentToken` | string | Required. The access token supplied by the get access token API. | ### Styles configuration | Property | Type | Description | |--------------|--------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------| | `base` | [fieldStyle](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-style) | Required. Styles to be applied to all fields. | | `cv2` | [fieldStyle](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-style) | Styles to override the base styles for the cv2 field. | | `cardNumber` | [fieldStyle](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-style) | Styles to override the base styles for the card number field. | | `expiryDate` | [fieldStyle](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-style) | Styles to override the base styles for the expiry date field. | | `cardName` | [fieldStyle](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-style) | Styles to override the base styles for the card name field. | | `cardIcon` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied to the card icon. | | `form` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied HTML form element containing all the fields. | #### Field style | Property | Type | Description | |------------------|--------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------| | `default` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied when the field is in its initial state. | | `focus` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied when the field has focus. | | `error` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied when the field has failed validation. | | `valid` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied when the field has passed validation. | | `errorFocus` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied when the field has focus and is in an error state. | | `validFocus` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied when the field has focus and is valid. | | `container` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied to the div wrapping the label and the input field. | | `label` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied to the label. | | `validationText` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied to the validation message. Only applicable if `text.(cardName \|cardNumber\|expiryDate\|cv2).showValidation` is `true`.| | `validationIcon` | [JavaScript CSS properties](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Properties_Reference) | Styles to be applied to the validation message icon. Only applicable if `text.(cardName \|cardNumber\|expiryDate\|cv2).showValidation` is `true`. E.g., to set the icon colour to purple set this property to `{ backgroundColor: 'purple' }`| ### Text configuration | Property | Type | Description | |--------------|--------------------------|------------------------------------------------------------------------| | `cardName` | [fieldText](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-text) | Config to override the default card name placeholder and label text. | | `cardNumber` | [fieldText](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-text) | Config to override the default card number placeholder and label text. | | `expiryDate` | [fieldText](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-text) | Config to override the default cv2 placeholder and label text. | | `cv2` | [fieldText](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#field-text) | Config to override the default expiry date placeholder and label text. | #### Field text | Property | Type | Description | |------------------|---------|---------------------------------------------------------------------------------| | `label` | string | Required. Text to replace the default label text. | | `placeholder` | string | Required. Text to replace the default placeholder text. (Empty will be ignored) | | `showValidation` | boolean | Option to show the validation message. Defaults to false if not set. | ### Button configuration | Property | Type | Description | |----------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `colour` | string | It defaults to black, but it can optionally be changed to white. | | `type` | string | It defaults to plain (payment button without additional text), but it can optionally be changed to book (Book with GooglePay/ApplePay), buy, checkout, donate or order. | ### Error messages This allows overriding of the default error messages. This will override both the messages passed to displayErrorsCallback and the message displayed if showValidation is set to true. | Property | Type | Description | |----------------------------|--------|------------------------------------------------------------------------| | `cardNameRequired` | string | Card name isn't entered. | | `cardNameInvalid` | string | Invalid card name is entered. | | `cardNumberRequired` | string | Card number isn't entered. | | `cardNumberInvalid` | string | Invalid card number is entered. | | `expiryDateRequired` | string | Card expiry date isn't entered. | | `expiryDateInvalid` | string | Invalid card expiry date is entered. | | `expiryDateMustBeInFuture` | string | Card expiry date isn't in the future. | | `cv2Required` | string | [CV2](https://en.wikipedia.org/wiki/Card_security_code) isn't entered. | | `cv2Invalid` | string | Invalid CV2 is entered. | ### Card callbacks | Property | Type | Description | |--------------------|-----------------------------|------------------------------------------------------------------------------------------------| | `onFormComplete` | function | An optional function which is called once the form is complete and all input values are valid. | | `onFormFieldValid` | function(fieldName: string) | An optional function which is called once a form field input is valid. | ### Wallet callbacks | Property | Type | Description | |----------------------|----------|-------------------------------------------------------------------------------------------------| | `onPaymentCancelled` | function | An optional function which is called if the user closes the wallet payment form without paying. | | `onPaymentInitiated` | function | An optional function which is called when the wallet payment button is clicked. | ## Validation error | Property | Type | Description | |-------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `errorType` | string | The type of validation error that has occured. For the card component this can be one of the following: `cardNameRequired`, `cardNameInvalid`, `cardNumberRequired`, `cardNumberInvalid`, `expiryDateRequired`, `expiryDateInvalid`, `expiryDateMustBeInFuture`, `cv2Required`, or `cv2Invalid`. | | `message` | string | Message detailing the validation error for displaying to the user. | ## Execute payment ```js card.executePayment(additionalInfo) .then(function(data){ /*handle response here*/ }).catch(function(data){ /*handle failure here*/ } ``` When the promise is fulfilled the following object will be passed. ## Transaction result | Property | Type | Description | |--------------|----------------------------|---------------------------------------------------------------------------| | `statusCode` | [statusCode](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#status-code) | Indicated the status of the transaction. 0 for a successful transaction. | | `authCode` | string | If the transaction was successful, then the auth code is passed out here. | | `message` | string | This gives a more detailed description of the status of the transaction. | ### Status code | Status Code | Result | Description | |-------------|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `0` | Successful | The transaction was successful. | | `3` | Authorizing | The card holder hasn't completed 3DS, this status will only be seen on the REST API. | | `4` | Referred | The card issuer has parked the transaction awaiting contact with the customer before proceeding to authorize or decline the transaction. | | `5` | Declined | The transaction was declined by the card issuer or acquiring bank. | | `20` | Duplicate Transaction | The transaction which was processed was a duplicate. Ensure each transaction has a unique OrderId. | | `30` | Failed | Error executing transaction. | | `400` | Invalid Request | The request has failed validation by our servers and the transaction hasn't been submitted to the gateway. Possible causes for this are invalid transaction type or other data in the request. | | `401` | Issue with Access Token | The access token being used isn't valid, the transaction hasn't been submitted to the gateway. This can be caused if the token has already been used or the 30 minute expiry time has elapsed. | | `404` | No Access Token Supplied | No access token has been supplied to Connect-E. Transaction hasn't been submitted to the gateway. | | `500` | Internal Server Error | There's been an error submitting the transaction, please check the REST API for the status of the transaction. | ## Additional information The user's email address and billing address can be passed as the optional additionalInfo object as defined below. These values will override those set when the access token was created. | Property | Type | Description | |--------------------|-------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `userEmailAddress` | string | This email will be checked with the card issuer to provide additional security. | | `userPhoneNumber` | string | The cardholder's phone number. | | `billingAddress` | [address](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#address) | This address will be checked with the card issuer to provide additional security. | | `shippingDetails` | [shippingDetails](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#shipping-details) | Shipping details for the order. | | `metaData` | `Map` | Meta data to be passed at execution time. This will be merged into MetaData passed via the REST API. This can be represented as a JSON object with only string values, other types aren't supported. | ## Shipping details | Property | Type | Description | |-----------|---------------------|------------------------------------| | `name` | string | Name order is being shipped to. | | `address` | [address](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#address) | Address order is being shipped to. | ## Address | Property | Type | Description | |---------------|--------|-------------------------------------------------------------------------------------------| | `address1` | string | Customer’s billing address line 1. | | `address2` | string | Customer’s billing address line 2. | | `address3` | string | Customer’s billing address line 3. | | `address4` | string | Customer’s billing address line 4. | | `city` | string | Customer’s billing address city. | | `state` | string | Customer’s billing address state or county. | | `postcode` | string | Customer’s billing address postcode or zipcode. | | `countryCode` | string | Customer’s billing address country code using ISO 3166–1 for example United Kingdom: 826. | --- ## Wallet >Learn how you can embed our prebuilt wallet component on your checkout page. The Dojo Wallet Component is a prebuilt JavaScript component for accepting payments on your checkout page. Use this integration option when you want full control over the payment flow and the look of your checkout page. In terms of implementation, integration contains: - Server-side: one API request to create a payment intent. - Client-side: set up the Dojo Wallet Component, which securely sends payment data to our server. - Webhooks: server-side endpoint to receive information about the payment. The payment flow is: 1. The customer visits the merchant's site and clicks the **Checkout** button. 2. The merchant client-side sends the customer's purchase information to the merchant server-side, and the merchant server-side sends this information to the Dojo server to [create a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-create-a-payment-intent). 3. The merchant client-side creates an instance of the [wallet component](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-add-the-component-to-your-checkout-page) using the `clientSessionSecret`. 4. The wallet component collects the customer's payment details, sends them to Dojo servers, and redirects the customer to the result page. 5. The merchant server receives a [webhook notification](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-4-handle-post-payment-events) when the payment is completed. ![](https://docs.dojo.tech/images/flow-wallet.jpg) **Flow diagram: Flow Wallet** ```mermaid sequenceDiagram actor C as Customer participant MC as Merchant Client-side participant MS as Merchant Server-side participant D as dojo C->>MC: Clicks "Checkout" MC->>MS: Sends information about customer purchases MS->>D: POST /payment-intents D-->>MS: PaymentIntent object MS-->>MC: Returns clientSessionSecret C->>D: Enters payment details and clicks "Pay" D-->>MC: Redirects to the result page D->>MS: Sends webhooks ``` > **Info:** If you’re looking for a low-code option, take a look at our [pre-built checkout](https://docs.dojo.tech/payments/checkout-page). > ## How to process a payment Step-by-step guide: 1. [Add the component to your checkout page](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-add-the-component-to-your-checkout-page). 2. [Set up Dojo Wallet Component](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-2-set-up-dojo-wallet-component). 3. [Create a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-create-a-payment-intent). 4. [Handle post-payment events](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-4-handle-post-payment-events). 5. [Test and go live](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-5-test-and-go-live). ### Before you start To enable Apple Pay, you must host the [domain verification file](https://cdn.dojo.tech/payments/assets/ApplePay/apple-developer-merchantid-domain-association) on each domain you want to use, including subdomains, under the following path: `https://yourdomain/.well-known/apple-developer-merchantid-domain-association`. Make sure that the file is downloadable and served at the correct location, as Apple will use this location to verify the validity of your domain. If your domain is protected from public access, and you wish to complete domain verification, you should allow [Apple IP Addresses for Domain Verification](https://developer.apple.com/documentation/apple_pay_on_the_web/setting_up_your_server/#3179116). #### Terms and Conditions - By integrating Apple Pay, you adhere to the [Apple Pay APIs Acceptable Use Policy](https://developer.apple.com/apple-pay/acceptable-use-guidelines-for-websites/) and accept the terms and conditions defined in the [Apple Pay Web Merchant Terms and Conditions](https://developer.apple.com/apple-pay/terms/apple-pay-web/). - By integrating Google Pay, you adhere to the [Google Pay APIs Acceptable Use Policy](https://payments.developers.google.com/terms/aup) and accept the terms defined in the [Google Pay API Terms of Service](https://payments.developers.google.com/terms/sellertos). ### Step 1. Add the component to your checkout page Include the Dojo `client.js` script in your checkout page. This script must always load directly from `cdn.dojo.tech` to remain PCI-compliant. You can’t include it in a bundle or host a copy of it yourself. ```html title="index.html" ``` Add empty a placeholder `div` to your checkout page to create a payment form. For example: ```html title="index.html" Wallet component Payment Complete
Status Code
Auth Code
Message
``` ### Step 2. Set up Dojo Wallet Component Next, in your JavaScript file, create an instance of Dojo: ```js title="script.js" .then(response => response.json()) .then(function (data) { const config = { containerId: 'demo-payment-wallet', paymentDetails: { paymentToken: data.clientSessionSecret, }, buttonConfig: { color: 'black', type: 'plain' }, emailRequired: true, billingAddressRequired: false, shippingAddressRequired: false } const wallet = new Dojo.WalletPayment(config, displayErrorsCallback, paymentComplete); function paymentComplete(response) { document.getElementById('demo-payment-wallet').hidden = true; document.getElementById('demo-result').hidden = false; document.getElementById('status-code').innerText = response.statusCode; document.getElementById('auth-code').innerText = response.authCode; document.getElementById('message').innerText = response.message; } ``` See the [optional configuration](https://docs.dojo.tech/payments/pay-at-table/configuration) for a complete list of parameters that you can use. ### Step 3. Create a payment intent Call a server-side endpoint to create a payment intent, for example: ```js title="script.js" fetch('/checkout', { // Declare what type of data we're sending headers: { 'Content-Type': 'application/json' }, // Specify the method method: 'POST', mode: 'no-cors', // A JSON payload body: JSON.stringify({ "greeting": "" }) }) ``` To create a payment intent, the following parameters are required: - `amount`: This includes the currency and value, in minor units, for example, "1000" for 10.00 GBP. - `reference`: Your unique reference for the payment intent. - `paymentMethods: "Wallet"`: The payment method that customers can use to pay. Here's an example of how to create a payment intent on your server-side: ```py title="server.py" # call post payment-intent payload = json.dumps({ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order 245", "paymentMethods": ["Wallet"] }) headers = { 'Content-Type': "application/json", 'Version': "2024-02-05", 'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ" # <-- Change to your secret key } conn.request("POST", "/payment-intents/", payload, headers) # handling the response from POST res = conn.getresponse() data = res.read() resp_data = {} resp_data['clientSessionSecret'] = json.loads(data)["clientSessionSecret"] print(resp_data) json_data = json.dumps(resp_data) resp = app.response_class( response=json_data, mimetype='application/json' ) return resp ``` See the [API reference](https://docs.dojo.tech/api#operation/PaymentIntents_CreatePaymentIntent) for a complete list parameters that you can use. ### Step 4. Handle post-payment events ### Step 5. Test and go live Before going live, test your integration. #### Testing Apple Pay To enable test cards for Apple Pay, you must have an Apple Sandbox Tester Account, then you will be able to add test cards into your Apple Wallet. See [Apple's Sandbox Testing Documentation](https://developer.apple.com/apple-pay/sandbox-testing/) to setup your Sandbox Tester Account and check the section Test Cards for Apps and the Web to see the full list of supported test cards by Apple. Although our test payment gateway doesn't support all of them, so if you want to test successful cases, please use the cards listed in the Test Cards section. If you aren't enrolled into the Apple Developer Program and need a tester account, please contact our support team for further instructions. #### Testing Google Pay The Google Pay [Test Card Suite](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) allows you to test Google Pay without the need of adding real cards to Google accounts. To instantly view these cards in your Google Account TEST environment, join [Google's User Group](https://groups.google.com/g/googlepay-test-mode-stub-data). All test cards will be automatically added to your account. --- ## Next steps [![](https://docs.dojo.tech/images/dojo-icons/AnchorSimple.svg) **Set up notification webhooks** Use webhooks to receive updates on your payments.](../../../../development-resources/webhooks) [![](https://docs.dojo.tech/images/dojo-icons/Settings.svg) **Configure Dojo Components** Find out how you can configure Dojo's components.](./configuration) [![](https://docs.dojo.tech/images/dojo-icons/TickCircle.svg) **Check your integration** Check off these steps before launching your integration in production.](checklist) [![](https://docs.dojo.tech/images/dojo-icons/Filters.svg) **Manage payments** Learn how to capture or reverse payments, retrieve payment details, or change payment amount.](../../../manage-payments) --- ## Online payments You can create powerful custom integrations with the [Dojo API](https://docs.dojo.tech/api), building around the central concept of the [payment intent](https://docs.dojo.tech/manage-payments/payment-intent). Online payments and in-person [Pay at Counter](https://docs.dojo.tech/payments/in-person-payments/pay-at-counter/introduction) transactions are both covered under the Dojo API. Dojo has also designed some ready-made online payments solutions that can be used to speed up integration for online payments. [![](https://docs.dojo.tech/images/dojo-icons/Bill.svg) **Checkout page** Discover the Dojo Prebuilt Checkout.](checkout-page) [![](https://docs.dojo.tech/images/dojo-icons/Wallet.svg) **Components** Use our ready-made JavaScript components.](components) [![](https://docs.dojo.tech/images/dojo-icons/WifiHigh.svg) **Payment links** Accept payments from customers without needing a full website.](payment-links) [![](https://docs.dojo.tech/images/dojo-icons/Laptop.svg) **Virtual terminal** Securely process phone and mail orders using your computer or mobile device.](virtual-terminal) --- ## Go-live checklist(Payment-links) > Check off these steps before launching your integration in production. The steps below will help to ensure you have a complete implementation. **Test in the sandbox** Before going live, test your integration in the [sandbox](https://docs.dojo.tech/development-resources/portal#sandbox-and-production-environments). For each payment method that you offer: * Make a successful payment. * Make an unsuccessful payment. Use the test card numbers below to make payments: **Check the result** Make your first live API call to make sure that your production key is working. Follow the payment link you generated to see the result. For the production environment, there should be no yellow label **Sandbox**. --- ## Payment links >Embed or share a link to the [Dojo Prebuilt Checkout](https://docs.dojo.tech/payments/accept-payments/online-payments/checkout-page), to start accepting payments anytime, anywhere. Payment links are a quick and simple way to accept payments from customers without needing a full website. Payments links provide complete flexibility for customers to pay across devices. To complete payment, each customer is issued with a unique link which will direct them to Dojo's secure checkout page. This checkout page is completely customizable, so you can design a checkout flow to fit your brand. You can create a payment link via the Dojo customer app or directly using the Dojo Payments API. If you are using the app, you can generate new links with no coding required. Simply generate a new link each time you wish to create an order. You can also automate the process using the Payments API, but some developer configuration will be required to set this up. Payment links expire after thirty days, and each link can only be used once. After a customer makes a successful payment, anyone else accessing that payment link in the future will see a "Payment successful" message. You can track any payment within the Dojo customer app. Once paid, you’ll see the funds in your next transfer. ![](https://docs.dojo.tech/images/payment-links.jpg) --- ## Ready to get started? [![](https://docs.dojo.tech/images/dojo-icons/MobileInformation.svg) **Dojo App** Create each payment link manually using Dojo App.](https://support.dojo.tech/hc/en-gb/articles/4415821097874-How-to-use-payment-links) [![](https://docs.dojo.tech/images/dojo-icons/BookBookmark.svg) **API step-by-step guide** Generate payment links automatically through the API.](/payments/accept-payments/online-payments/payment-links/step-by-step-guide) {/*Follow this style of linking*/} --- ## Step-by-step guide(Payment-links) >Learn how to generate payment links automatically through the API. In terms of implementation, the integration contains: - Server-side: one API request to create a payment intent. - WebHooks: at least one server-side endpoint, to receive information about the payment. The payment flow is: 1. The merchant server-side sends the payment information to the Dojo server to [create a payment intent](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-create-a-payment-link). 2. The merchant server-side generates a payment link and [sends it to the customer](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-2-send-the-payment-link-to-your-customer). 3. The customer opens the payment link, and they are redirected to the [Prebuilt Checkout Page](https://docs.dojo.tech/payments/checkout-page). This is hosted by Dojo. 4. The Prebuilt Checkout Page collects the customer's payment details and sends them to Dojo servers, then redirects the customer to the result page. 5. The merchant server receives a [WebHook notification](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-handle-post-payment-events) when the customer uses the payment link. ![](https://docs.dojo.tech/images/flow-payment-links.jpg) **Flow diagram: Flow Payment Links** ```mermaid sequenceDiagram actor C as Customer participant DC as dojo Client-side participant MS as Merchant Server-side participant DS as dojo Server-side C->>MS: Requests Payment Link MS->>DS: POST /payment-intents (paymentSource: "payment-links") DS-->>MS: PaymentIntent object MS-->>C: Sends Payment Link C->>DC: Opens Payment Link C->>DC: Enters payment details and clicks "Pay" DS-->>DC: Redirects to the result page DS->>MS: Sends webhooks ``` ## How to process a payment Step-by-step guide: 1. [Create a payment link](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-1-create-a-payment-link). 2. [Send the payment link to your customer](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-2-send-the-payment-link-to-your-customer). 3. [Handle post-payment events](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-3-handle-post-payment-events). 4. [Test and go live](https://docs.dojo.tech/payments/pay-at-table/go-live-checklist#step-4-test-and-go-live). ### Before you start ### Step 1. Create a payment link To create a payment link, first call a server-side endpoint to create a payment intent. The following parameters are required: - `amount`: This includes the currency and value, in minor units, for example, "1000" for 10.00 GBP. - `reference`: Your unique reference for the payment intent. - `isNotOnlineCheckout`: Set to true to start accepting payment links without an online checkout integration. Defaults to false if omitted. Requires a verified partner integration for use in production. Here's an example of how to create a payment intent for 10 GBP on your server-side: ```py title="server.py" @app.route('/', methods=['GET', 'POST']) def hello(): print(request.get_json()) # parse as JSON conn = http.client.HTTPSConnection("api.dojo.tech") payload = json.dumps({ "amount": { "value": 1000, "currencyCode": "GBP" }, "reference": "Order 245", }) headers = { 'Content-Type': "application/json", 'Version': "2024-02-05", 'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ" # <-- Change to your secret key } conn.request("POST", "/payment-intents/", payload, headers) res = conn.getresponse() data = res.read() last_id = json.loads(data)["id"] url = 'https://pay.dojo.tech/checkout/' + last_id return redirect(url) ``` See the [API reference](https://docs.dojo.tech/api#operation/PaymentIntents_CreatePaymentIntent) for a complete list of parameters that can be used for payment intent creation. ### Step 2. Send the payment link to your customer After receiving the request, Dojo creates a payment intent and returns its unique ID: ```json { "id": "pi_sandbox_RBMHTJ4fIkmSppDILZVCGw", ... } ``` Return this ID to the client-side and use it to create a link in the following format: `https://pay.dojo.tech/checkout/{{id}}` Send the link to your customer through chat or email. When the customer opens the link, they'll redirect to Dojo Prebuilt Checkout Page. After the customer fills in their payment information, Dojo processes the payment and redirects the customer to the success page. ### Step 3. Handle post-payment events ### Step 4. Test and go live Before going live, test your integration using the test card numbers: --- ## Next steps [![](https://docs.dojo.tech/images/dojo-icons/AnchorSimple.svg) **Set up notification WebHook** Use WebHooks to receive updates related to your payments.](../../../../development-resources/webhooks) [![](https://docs.dojo.tech/images/dojo-icons/Settings.svg) **Configure Dojo Checkout Page** Find out how to add another payment method or shipping address form to the page.](../checkout-page/configuration) [![](https://docs.dojo.tech/images/dojo-icons/TickCircle.svg) **Check your integration** Check off these steps before launching your integration in production.](checklist) [![](https://docs.dojo.tech/images/dojo-icons/Filters.svg) **Manage payments** Learn how to capture or reverse payments, retrieve payment details or change payments amount.](../../../manage-payments) --- ## Go-live checklist(Virtual-terminal) > Check off these steps before launching your integration in production. The following steps ensure you have a complete implementation. **Ensure that your business is PCI-compliant.** You must submit the [Self-Assessment Questionnaire A](https://listings.pcisecuritystandards.org/documents/PCI-DSS-v3_2-SAQ-C_VT-rev1_1.pdf) to [Dojo](https://support.dojo.tech/hc/en-gb). **Contact Dojo to enable Virtual Terminal (VT) payments** As a Dojo customer, if your business is enabled for card-not-present (CNP) payments, you can set up your own virtual terminal with Dojo. To enable a virtual terminal in your account, contact [Dojo customer support](https://support.dojo.tech/hc/en-gb). **Ensure that your VT implementation is ready** You must have either a [prebuilt checkout page](https://docs.dojo.tech/payments/checkout-page) or a [checkout component](https://docs.dojo.tech/payments/components) ready alongside your complete VT implementation to start accepting payments. **Test in the sandbox** Before going live, test your integration in the [sandbox](https://docs.dojo.tech/development-resources/portal#sandbox-and-production-environments). For each payment method that you offer: * Make a successful payment. * Make an unsuccessful payment. Use the test card numbers below to make payments: > **Note:** When using a test card with [3D security (3DS)](https://en.wikipedia.org/wiki/3-D_Secure), the virtual terminal will automatically skip all 3DS checks. > > > > > > > > > > > > > > > > > > > **Check the result** > > Make your first live API call to make sure that your production key is working. > Follow the payment link you generated to see the result. > For the production environment, there should be no yellow **Sandbox** label. > > > --- > > ## Securing VT transactions > > > Learn about securing virtual terminal transactions for your business. > > To ensure that your virtual terminal transactions are secure, you must understand the following: > > - **Limited authentication**: Virtual terminal transactions don’t require authentication, as their transactions take place over a phone call, email, or mail order. To enhance your security, you can add an [Address Verification Service (AVS)](https://en.wikipedia.org/wiki/Address_verification_service) check to your payment process. > > - **Understand chargebacks**: Chargebacks occur when customers dispute a transaction and request a refund from their issuing bank. Virtual terminals are prone to a high risk of chargebacks when compared to Payment Links. Ensure you implement [Strong Customer Authentication (SCA)](https://www.fca.org.uk/firms/strong-customer-authentication) to minimize chargebacks. > > - **Data breaches**: Virtual terminal transactions often involve the exchange of sensitive information, such as credit card details, personal data, and transaction history. By implementing robust security measures, securing your payment systems, and staying updated on the latest security practices, you can help prevent data breaches and protect your customers' confidential information. > > - **PCI compliance**: PCI sets strict security standards for handling cardholder data, to protect against unauthorized access. To minimize risk, your business must be PCI-compliant. > > --- > > ## Step-by-step guide(Virtual-terminal) > > Step-by-step guide to set up your own virtual terminal. > > ## Setup flow > > To set up a virtual terminal for your web app, do the following: > > **Info:** - This guide assumes that you are setting up your virtual terminal using Dojo’s [prebuilt checkout page](https://docs.dojo.tech/payments/checkout-page). Similarly, you can set up a virtual terminal with [components](https://docs.dojo.tech/payments/components) and [mobile integration](https://docs.dojo.tech/mobile-integration). ![](https://docs.dojo.tech/images/virtual-terminal.png) ## Step 1. Create a payment intent To create a payment intent, call a server-side endpoint. For that, the following parameters are required: - `amount`: This includes the currency and value, in minor units, for example, "1000" for 10.00 GBP. - `reference`: Your unique reference for the payment intent. - `cardHolderNotPresent: "true"`: Confirms that the card holder is not present during the transaction. > **Info:** - When `cardHolderNotPresent` is set to `true`, it means payments are made through the mail or over the telephone. They are a common use case for virtual terminals. > - To process these transactions, you must have a virtual terminal to accept payments over the phone, fax, email, or by mail. This type of transaction is common for businesses that operate remotely or have a significant online presence. > - Using `cardHolderNotPresent`, you can implement a virtual terminal in [components](https://docs.dojo.tech/payments/components) and [Mobile integration](https://docs.dojo.tech/mobile-integration). Here's an example of how to create a virtual terminal payment for 10 GBP: ```bash # The sandbox API key passed in 'authorization' is public. # Don’t submit any personally identifiable information in any requests made with this key. # Sign in to developer.dojo.tech to create your own private sandbox key and use that instead # for secure testing. curl -v --request POST \ --url https://api.dojo.tech/payment-intents \ --header 'content-type: application/json' \ --header 'authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \ --header 'version: 2022-07-04' \ --data '{ "amount":{ "value":1000, "currencyCode":"GBP" }, "reference":"Order 234", "cardHolderNotPresent": true }' ``` ## Step 2. Redirect to Dojo Checkout Page 1. After receiving the request, Dojo creates a payment intent and returns its unique ID: ```json { "id": "pi_sandbox_RBMHTJ4fIkmSppDILZVCGw", ... } ``` 2. Return this `id` to the client-side and use it to create a link in the following format: `https://pay.dojo.tech/checkout/{{id}}` 3. Share the link with your merchant. Clicking this link will render the checkout page at the merchant's end. :::warning Do not share this link with your customer. This link is for the **merchant use only**. ## Step 3. Request card details from the customer Next, the merchant requests card details from the customer over a call, email, or mail order. When the customer authorizes the merchant to make the payment, the merchant fills in the customer's card details on the checkout page. Dojo processes the payment and redirects to the success page. Finally, the customer is notified via email about the successful payment. ### Step 4. Handle post-payment events ### Step 5. Test and go live Before going live, test your integration using the test card numbers: --- --- ## Virtual terminal >Learn about accepting payments using a virtual terminal. A virtual terminal is an online interface that allows merchants to process payments without needing a physical card terminal. Virtual terminals are one of the ways you can handle [Card Not Present (CNP)](https://dojo.tech/articles/what-is-card-not-present/) payments. They enable you to securely process phone or mail orders using your computer or mobile device, without the need for a customer - or a physical card terminal - to be physically present. Virtual terminals are especially beneficial for remote businesses, such as service-based companies, and mobile businesses. With a virtual terminal, businesses can accept payments from any device with an internet connection. This flexibility is crucial for businesses looking to expand their customer base and provide a convenient payment option for their customers. > **Note:** Because the cardholder is present on the phone, you _can_ use Dojo’s virtual terminal to accept payments instantly. However, Dojo recommends [payment links](https://docs.dojo.tech/payments/accept-payments/online-payments/payment-links) as the most secure method for accepting CNP payments. > > > ## Can I set up a virtual terminal with Dojo? > > As a Dojo customer, if your business is enabled for CNP payments, you can set up your own virtual terminal. Contact [Dojo customer support](https://support.dojo.tech/hc/en-gb) for details. > > --- > > ## Ready to get started? > > > > [![](https://docs.dojo.tech/images/dojo-icons/MobileInformation.svg) **Dojo App** Accept payments with virtual terminal in your Dojo for Business app.](https://support.dojo.tech/hc/en-gb/articles/7949437308828-Take-remote-payments-with-the-virtual-terminal) > > [![](https://docs.dojo.tech/images/dojo-icons/BookBookmark.svg) **API step-by-step guide** Accept payments with your own virtual terminal using the API.](virtual-terminal/step-by-step-guide) > > > > --- > > ## Virtual terminal vs Payment links > > Know how Virtual Terminals are different from Payment Links. > > Virtual Terminals and [Payment Links](https://docs.dojo.tech/payments/payment-links) have some similarities but a number of key differences. > > | Feature | Virtual terminal | Payment links | > |---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| > | **Payment process flow** | Card details are entered by the merchant when the customer provides their credit card details over the phone, or through a mail order. The merchant enters these details into their payment terminal or e-commerce platform to process the transaction. | Card details are entered by the customer where the merchant generates a unique link for a specific amount and sends it to the customer via email, SMS, or other messaging platforms. The customer clicks on the link and is redirected to a secure page where they can enter their card details and complete the transaction. | > | **Security measures** | The risk of fraud in virtual terminals is relatively higher as the merchant manually inputs the card details received from the customer, making this method less secure. | This method is safer as the customer enters their own card details. These transactions require strong customer authentication (SCA), that is, [3DS 2.0](https://3dsecure2.com/), reducing the risk of fraud. | > | **Customer experience** | Virtual terminal payments can be less convenient for some customers, as this method requires direct interaction with the merchant. | Payment links are often considered more convenient, as the customer can pay at any time and on any device. The customer may not need to interact directly with the merchant to complete the payment. | > | **Merchant experience** | Virtual terminal payments can be more labor-intensive for the merchant, as they are required to manually input card details and handle sensitive customer information. | Payment links can be generated with minimal effort. The merchant does not need to handle sensitive card information. | > | **Industry applications** | Any small or large business that does not provide an online payment option. | Any business looking to simplify the payment process and improve customer experience with pay-by-link. | > > **Note:** Dojo recommends that you use payment links over virtual terminals as a more secure method for accepting payments.