Quick Start
Before you begin
You need an ElasticPay account and sandbox API keys. Find them in Settings > API Keys in the dashboard. Keys come in two types: secret (sk_sandbox_...) for server-side use and publishable (pk_sandbox_...) for client-side use.
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
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
- Authentication — key types and how to send them
- Accept a Payment — full integration guide
- Webhooks — receive real-time payment events