Step-by-step guide
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:
-
The merchant server-side sends the payment information to the Dojo server to create a payment intent.
-
The merchant server-side generates a payment link and sends it to the customer.
-
The customer opens the payment link, and they are redirected to the Prebuilt Checkout Page. This is hosted by Dojo.
-
The Prebuilt Checkout Page collects the customer's payment details and sends them to Dojo servers, then redirects the customer to the result page.
-
The merchant server receives a WebHook notification when the customer uses the payment link.

Flow diagram: Flow Payment Links
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:
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_.
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:
- Python
- C#
@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)
[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"
},
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 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:
{
"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
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 4. Test and go live
Before going live, test your integration using the test card numbers:
| Card Name | Card number | Expiry Date | CVV | 3D security | Status |
|---|---|---|---|---|---|
| No | Successful | ||||
| 2.0 | Successful | ||||
| No | Decline |
When you are ready to go live, switch your secret key to production one with the prefix sk_prod_.