Step-by-step guide
Learn how to create a setup intent and charge the card using the API.
During its lifecycle, the Setup Intent goes through a combination of the following statuses, depending upon your requirements.
| Status | Description |
|---|---|
Created | The setup intent is created. |
Authorized | The customer adds their card details and authorizes the setup intent. |
Expired | The setup intent expired after creation. |
CardExpired | The card entered has passed the expiry date and is no longer usable. |
Canceled | The setup intent in created state is deleted. |
Completed | The setup intent cycle is complete and the merchant has charged the customer's card. |
Closed | The authorized setup intent is also deleted. This is applicable when you set includeAuthorized to true using the DELETE /setup-intents endpoint. |
Flow diagram

Follow the steps below for a complete setup intent flow:
Step 1: Create a setup intent
To create a setup intent, use the following endpoint:
POST /setup-intents
In your request body, include the following:
reference: A reference number to track.intendedAmount: The amount you intend to collect from a customer in the future after a payment method is attached.merchantInitiatedTransactionType: The transaction type you intend to set up.terms: The agreed terms between you and your customer.
- When configuring the
intendedAmount, a customer will not be charged right away. The charge may vary depending upon the terms agreed between a customer and a merchant. - By default, you can create a setup intent with
captureMode: Autoonly.
Request example
The following code sample demonstrates creating a setup intent of 10.00 GBP.
- cURL
- PowerShell
- Python
- C#
# 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/setup-intents' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \
--header 'Version: 2024-02-05' \
--data '{
"reference": "Dojo Cafe | Booking request for Table 4",
"merchantInitiatedTransactionType": "NoShow",
"terms": "In case of no-show, the customer authorizes us to charge their card with table booking fee.",
"intendedAmount": {
"value": "1000",
"currencyCode": "GBP"
}
}'
# The sandbox API key passed in '$publicSandboxKey' 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.
$publicSandboxKey = "sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
Invoke-WebRequest `
-Uri 'https://api.dojo.tech/setup-intents' `
-Method POST `
-Headers @{
"version" = "2024-02-05"
"Authorization" = "Basic $publicSandboxKey"
} `
-ContentType 'application/json' `
-Body '{
"amount": {
"value": 1000,
"currencyCode": "GBP"
},
"merchantInitiatedTransactionType": "NoShow",
"reference": "Dojo Cafe | Booking request for Table 4",
"terms": "In case of no-show, the customer authorizes us to charge their card with table booking fee."
}'
# 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
import json
conn = http.client.HTTPSConnection("api.dojo.tech")
payload = json.dumps({
"amount": {
"value": 1000,
"currencyCode": "GBP"
},
"merchantInitiatedTransactionType": "NoShow",
"reference": "Dojo Cafe | Booking request for Table 4",
"terms": "In case of no-show, the customer authorizes us to charge their card with table booking fee."
})
// 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 setupIntentsClient = new SetupIntentsClient(new HttpClient(), new ApiKeyClientAuthorization("sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"));
var result = await setupIntentsClient.CreateAsync(new CreateSetupIntentRequest
{
IntendedAmount = new()
{
Value = 1000,
CurrencyCode = "GBP"
},
MerchantInitiatedTransactionType = MerchantInitiatedTransactionType.NoShow,
Reference = "Dojo Cafe | Booking request for Table 4",
Terms = "In case of no-show, the customer authorizes us to charge their card with table booking fee."
});
Once you've created a setup intent, the status is updated to ⦿ created.
Step 2. Redirect your customer to Dojo's Checkout page
After receiving the request, Dojo creates a setup intent and returns its unique ID in the following format:
{
"id": "si_sandbox_Oh69aQaQMUuNIPJcPrcRwQ",
...
}
-
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:
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 in their payment information on the Checkout page, Dojo server-side saves the card details and redirects the customer to the success page.
Once your customer authorizes their card in the setup intent, the status is updated to ⦿ authorized.
Step 3: Create a payment intent and charge the card
After a setup intent has been created and authorized, you can use the setupIntentId to create a payment intent and charge the card. When you are ready to charge the card, create a payment intent and then use the payment intent charge endpoint.
- You can charge the full amount only.
- For the payment intent you create, you can charge a card only once.
Charge a card using the Dojo API
To complete the process of charging a card, ensure you do the following:
-
Create a payment intent and pass the
setupIntentIdto the request.POST /payment-intents
{ ...
"setupIntentId": "si_sandbox_<secret-key>",
}Request example
The following code sample demonstrates creating a payment intent of 10.00 GBP using the setup intent ID created in step 1:
- cURL
- PowerShell
- Python
- C#
# 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": "Dojo Cafe | Table no. 4.",
"setupIntentId": "<setupIntentId>"
}'# The sandbox API key passed in '$publicSandboxKey' 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.
$publicSandboxKey = "sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
Invoke-WebRequest `
-Uri 'https://api.dojo.tech/payment-intents' `
-Method POST `
-Headers @{
"Version" = "2024-02-05"
"Authorization" = "Basic $publicSandboxKey"
} `
-ContentType 'application/json' `
-Body '{
"amount": {
"value": 1000,
"currencyCode": "GBP"
},
"reference": "Dojo Cafe | Table no. 4.",
"setupIntentId": "<setupIntentId>"
}'# 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
import json
conn = http.client.HTTPSConnection("api.dojo.tech")
payload = json.dumps({
"amount": {
"value": 1000,
"currencyCode": "GBP"
},
"reference": "Dojo Cafe | Table no. 4.",
"setupIntentId": "<setupIntentId>"
})
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()
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 paymentIntentsClient = new PaymentIntentsClient(new HttpClient(), new ApiKeyClientAuthorization("sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"));
var result = await paymentIntentsClient.CreatePaymentIntentAsync(new CreatePaymentIntentRequest
{
Amount = new()
{
Value = 1000,
CurrencyCode = "GBP"
},
Reference = "Dojo Cafe | Table no.4.",
SetupIntentId = "<setupIntentId>",
});Once you create a payment intent to charge the card, the setup intent status is still ⦿ authorized.
-
Then initiate a charge to complete the process:
POST /payment-intents/{paymentIntentId}/charge
In your request, include:
paymentIntentId: This identifies the payment intent to be charged.Request example
The following code sample demonstrates initiating a charge of 10.00 GBP against the payment intent ID created in the above step:
- cURL
- PowerShell
- Python
- C#
# 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/pi_sandbox_Dcqx7k8pUUKedgB6wD1J1A/charge \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \
--header 'Version: 2024-02-05'# The sandbox API key passed in '$publicSandboxKey' 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.
$publicSandboxKey = "sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
Invoke-WebRequest `
-Uri 'https://api.dojo.tech/payment-intents/pi_sandbox_Dcqx7k8pUUKedgB6wD1J1A/charge' `
-Method POST `
-Headers @{
"Version" = "2024-02-05"
"Authorization" = "Basic $publicSandboxKey"
}# 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")
headers = {
'Version': "2024-02-05",
'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
}
conn.request("POST", f"/payment-intents/pi_sandbox_Dcqx7k8pUUKedgB6wD1J1A/charge", headers=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 chargeResponse = new PaymentIntentsClient(new HttpClient(), new ApiKeyClientAuthorization("sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"));
var result = await chargeResponse.ChargePaymentIntentAsync("pi_sandbox_Dcqx7k8pUUKedgB6wD1J1A");Once you charge the card successfully, the setup intent status is updated to ⦿ completed.
Check setup intent status
GET /setup-intents/{setupIntentId}
Every time you perform an action with the Setup IntentAPI, it transitions through a state. We recommend that you subscribe to notifications to check the current status of your setup intent.
In your request, include:
setupIntentId: identifies the setup intent you want to track.
For the full API specification, see the API reference.
Request example
The following example shows how to check the status of the setup intent:
- cURL
- PowerShell
- Python
- C#
# 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/setup-intents/si_sandbox_Oh69aQaQMUuNIPJcPrcRwQ' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ' \
--header 'Version: 2024-02-05'
# The sandbox API key passed in '$publicSandboxKey' 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.
$publicSandboxKey = "sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
# Replace <PAYMENT_INTENT_ID> with ID of payment intent you want to cancel.
Invoke-WebRequest `
-Uri 'https://api.dojo.tech/setup-intents/<PAYMENT_INTENT_ID>' `
-Method GET `
-Headers @{
"Version" = "2024-02-05"
"Authorization" = "Basic $publicSandboxKey"
}
# 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
import json
conn = http.client.HTTPSConnection("api.dojo.tech")
headers = {
'Version': "2024-02-05",
'Authorization': "Basic sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"
}
conn.request("GET", f"/setup-intents/{setupIntentId}", headers=headers)
res = conn.getresponse()
data = res.read()
resp_data = {}
resp_data['status'] = json.loads(data)["status"]
print(resp_data)
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 setupIntentsClient = new SetupIntentsClient(new HttpClient(), new ApiKeyClientAuthorization("sk_sandbox_c8oLGaI__msxsXbpBDpdtwJEz_eIhfQoKHmedqgZPCdBx59zpKZLSk8OPLT0cZolbeuYJSBvzDVVsYvtpo5RkQ"));
var result = await setupIntentsClient.GetByIdAsync("<Setup intent ID>");
Console.WriteLine(result.Status);
The response will return information about the setup intent and its status.