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:
-
The customer visits the merchant's site and clicks the Checkout button.
-
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.
-
The merchant client-side creates an instance of the wallet component using the
clientSessionSecret. -
The wallet component collects the customer's payment details, sends them to Dojo servers, and redirects the customer to the result page.
-
The merchant server receives a webhook notification when the payment is completed.

Flow diagram: Flow Wallet
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
If you’re looking for a low-code option, take a look at our pre-built checkout.
How to process a payment
Step-by-step guide:
Before you start
Before you begin to integrate, make sure you have followed the Getting started guide and got your API keys.
For the test environment, use your secret key with the prefix sk_sandbox_.
To enable Apple Pay, you must host the domain verification file 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.
Terms and Conditions
-
By integrating Apple Pay, you adhere to the Apple Pay APIs Acceptable Use Policy and accept the terms and conditions defined in the Apple Pay Web Merchant Terms and Conditions.
-
By integrating Google Pay, you adhere to the Google Pay APIs Acceptable Use Policy and accept the terms defined in the Google Pay API Terms of Service.
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.
<head>
<link rel="stylesheet" href="static/styles.css">
<script src="https://cdn.dojo.tech/payments/v1/client.js"></script>
<script src="static/script.js"></script>
</head>
Add empty a placeholder div to your checkout page to create a payment form.
For example:
<body>
<h1>Wallet component</h1>
<div id="demo-payment-wallet"></div>
<div id="errors"></div>
<div id="demo-result" hidden>
<h5>Payment Complete</h5>
<dl>
<dt>Status Code</dt>
<dd id="status-code"></dd>
<dt>Auth Code</dt>
<dd id="auth-code"></dd>
<dt>Message</dt>
<dd id="message"></dd>
</dl>
</div>
</body>
Step 2. Set up Dojo Wallet Component
Next, in your JavaScript file, create an instance of Dojo:
.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 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:
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:
- Python
- C#
# 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
[HttpPost]
public async Task<string> CheckoutAsync(CheckoutRequest checkoutRequest, CancellationToken cancellationToken)
{
try
{
var result = await _paymentIntentsClient.CreatePaymentIntentAsync(new CreatePaymentIntentRequest
{
Amount = new Money()
{
Value = checkoutRequest.Amount,
CurrencyCode = "GBP"
},
PaymentMethods = new List<PaymentMethod>() { PaymentMethod.Card , PaymentMethod.Wallet},
Description = checkoutRequest.Description,
Reference = Guid.NewGuid().ToString() // can be you order id
}, cancellationToken);
return result.Id;
}
catch (ApiClientException<ProblemDetails> e)
{
// Check Dojo Documentation for error handling https://docs.dojo.tech/api#section/Errors
_logger.LogError(e, $"StatusCode:{e.Result.Status}, Response: {e.Result.Detail}, TraceId: {e.Result.TraceId}");
throw;
}
catch (ApiClientException e)
{
_logger.LogError(e, "Unhandled error");
throw;
}
}
See the API reference for a complete list parameters that you can use.
Step 4. Handle post-payment events
Use webhooks to receive information about the payment. We send a payment_intent.status_updated event when the payment is completed (captured, refunded, released, reversed, canceled).
Here's an example of how to subscribe to the payment_intent.status_updated event:
- cURL
- PowerShell
- Python
- C#
- PHP
# 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"
}'
# This is a public sandbox API key.
# 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.
$publicSandboxKey = "sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
Invoke-WebRequest `
-Uri 'https://api.dojo.tech/webhooks' `
-Method POST `
-Headers @{
"version" = "2024-02-05"
"Authorization" = "Basic $publicSandboxKey"
} `
-ContentType 'application/json' `
-Body '{
"events": [ "payment_intent.status_updated" ],
"url": "https://example.com/incoming-events"
}'
# 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.
import http.client
conn = http.client.HTTPSConnection("api.dojo.tech")
payload = "{\"events\":[\"payment_intent.status_updated\"],\"url\":\"https://example.com/incoming-events\"}"
headers = {
'Content-Type': "application/json",
'Version': "2024-02-05",
'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ" # <-- Change to your secret key
}
conn.request("POST", "/webhooks", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
conn.close()
// The sandbox API key passed in 'ApiKeyClientAuthorization' 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.
var webhooksClient = new Dojo.Net.WebhooksClient(new HttpClient(), new ApiKeyClientAuthorization("sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"));
webhooksClient.SubscribeAsync(new SubscriptionRequest()
{
Events = new List<string>() { "payment_intent.status_updated" },
Url = new Uri("https://example.com/incoming-events")
});
<?php
// The sandbox API key used in this example 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.
namespace Test;
require_once "vendor/autoload.php";
use Dojo_PHP\ApiFactory;
use Dojo_PHP\Model\SubscriptionRequest;
$apiKey = "sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ";
$api = ApiFactory::createWebhooksApi($apiKey);
$req = new SubscriptionRequest(["url" => "https://example.com/incoming-events", "events" => ["payment_intent.status_updated"]]);
$api->webhooksSubscribe(\Dojo_PHP\API_VERSION, $req);
If you haven't set up webhooks yet, review our webhooks guide.
Step 5. Test and go live
Before going live, test your integration.
When you are ready to go live, switch your secret key to production one with the prefix sk_prod_.
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 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 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. All test cards will be automatically added to your account.