Quick Start
Before you begin
Section titled “Before you begin”You need an ElasticPay account and sandbox API keys. Find them under Developer → API keys in the dashboard, or go straight to dashboard.elasticpay.co/developers. If you don’t have an account yet, see Get a sandbox API key.
Keys come in two types: secret (sk_sandbox_...) for server-side use and publishable (pk_sandbox_...) for client-side use.
Create a payment intent
Section titled “Create a payment intent”A payment intent represents a single payment attempt. Create one server-side with an amount (in cents) and currency.
curl -X POST https://api.elasticpay.co/api/v1/payment_intents \ -H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"amount": 2000, "currency": "AUD"}'const response = await fetch('https://api.elasticpay.co/api/v1/payment_intents', { method: 'POST', headers: { 'Authorization': 'Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: 2000, currency: 'AUD' }),});const pi = await response.json();console.log(pi.id); // pi_0abc123...console.log(pi.client_secret); // pass to the widgetimport requests
response = requests.post( 'https://api.elasticpay.co/api/v1/payment_intents', headers={'Authorization': 'Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}, json={'amount': 2000, 'currency': 'AUD'},)pi = response.json()print(pi['id']) # pi_0abc123...print(pi['client_secret']) # pass to the widget<?phpuse GuzzleHttp\Client;
$client = new Client([ 'base_uri' => 'https://api.elasticpay.co', 'headers' => [ 'Authorization' => 'Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type' => 'application/json', ],]);
$response = $client->post('/api/v1/payment_intents', [ 'json' => ['amount' => 2000, 'currency' => 'AUD'],]);$pi = json_decode($response->getBody(), true);echo $pi['id']; // pi_0abc123...echo $pi['client_secret']; // pass to the widgetrequire 'faraday'require 'json'
conn = Faraday.new('https://api.elasticpay.co') do |f| f.request :json f.response :jsonendconn.headers['Authorization'] = 'Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'conn.headers['Content-Type'] = 'application/json'
res = conn.post('/api/v1/payment_intents') { |r| r.body = { amount: 2000, currency: 'AUD' } }pi = res.bodyputs pi['id'] # pi_0abc123...puts pi['client_secret'] # pass to the widgetusing System.Net.Http;using System.Net.Http.Headers;using System.Net.Http.Json;
using var http = new HttpClient { BaseAddress = new Uri("https://api.elasticpay.co") };http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
var response = await http.PostAsJsonAsync( "/api/v1/payment_intents", new { amount = 2000, currency = "AUD" });var pi = await response.Content.ReadFromJsonAsync<JsonDocument>();Console.WriteLine(pi.RootElement.GetProperty("id").GetString());Console.WriteLine(pi.RootElement.GetProperty("client_secret").GetString());Response:
{ "id": "pi_0abc123def456ghi789jkl012mn", "amount": 2000, "currency": "AUD", "status": "requires_payment_method", "client_secret": "pi_0abc123def456ghi789jkl012mn_secret_xyz987", "livemode": false, "created_at": "2025-01-15T10:00:00Z"}The client_secret is passed to the widget to collect card details. Keep the payment intent id on your server.
Confirm the payment
Section titled “Confirm the payment”After the widget tokenises the card and returns a pm_xxx, confirm the payment:
curl -X POST https://api.elasticpay.co/api/v1/payment_intents/pi_0abc123def456/confirm \ -H "Authorization: Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"payment_method": "pm_0xyz789abc123def456ghi012jkl"}'const res = await fetch( 'https://api.elasticpay.co/api/v1/payment_intents/pi_0abc123def456/confirm', { method: 'POST', headers: { 'Authorization': 'Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', 'Content-Type': 'application/json', }, body: JSON.stringify({ payment_method: 'pm_0xyz789abc123def456ghi012jkl' }), });const result = await res.json();console.log(result.status); // 'succeeded'result = requests.post( 'https://api.elasticpay.co/api/v1/payment_intents/pi_0abc123def456/confirm', headers={'Authorization': 'Bearer sk_sandbox_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'}, json={'payment_method': 'pm_0xyz789abc123def456ghi012jkl'},).json()print(result['status']) # 'succeeded'$result = json_decode($client->post( '/api/v1/payment_intents/pi_0abc123def456/confirm', ['json' => ['payment_method' => 'pm_0xyz789abc123def456ghi012jkl']])->getBody(), true);echo $result['status']; // 'succeeded'res = conn.post('/api/v1/payment_intents/pi_0abc123def456/confirm') do |r| r.body = { payment_method: 'pm_0xyz789abc123def456ghi012jkl' }endputs res.body['status'] # 'succeeded'var confirm = await http.PostAsJsonAsync( "/api/v1/payment_intents/pi_0abc123def456/confirm", new { payment_method = "pm_0xyz789abc123def456ghi012jkl" });var result = await confirm.Content.ReadFromJsonAsync<JsonDocument>();Console.WriteLine(result.RootElement.GetProperty("status").GetString()); // succeededA status of succeeded means the payment is complete. For async processing you may see processing — listen for the payment_intent.succeeded webhook as the authoritative signal.
Next steps
Section titled “Next steps”- Authentication — key types and how to send them
- Take a One-Off Payment — the full integration path
- Webhooks — receive real-time payment events