Payment Gateway SDK
Welcome to the Payment Gateway SDK documentation. Whether you're building a SaaS application, an e-commerce platform, or a marketplace, accepting payments is critical to your business. Our SDK makes it simple to integrate secure, PCI-compliant payment processing into your application with just a few lines of code.
This documentation is designed for developers who want to get up and running quickly while understanding the underlying concepts. We provide code examples in multiple languages (Node.js, Python, Ruby, and cURL), comprehensive API references, and best practices for production deployments. Let's get started!
Quick Start
Get started with the Payment Gateway SDK in minutes. Install the package and start processing payments. Our SDK handles all the complexity of payment processing,tokenization, 3D Secure authentication, webhook management, and more,so you can focus on building your product.
Install
Add the SDK to your project
Authenticate
Configure with your API key
Process
Start accepting payments
Installation
npm install @paymentgateway/sdkAuthentication
All API requests require authentication using your API key. You can find your API key in the dashboard under Settings → API Keys. We use HTTP Basic Authentication where your API key is the username and the password is left empty.
We provide two types of API keys: test keys (starting with sk_test_) for development and live keys (starting with sk_live_) for production. Test keys interact with our sandbox environment where no real money is processed. Live keys process real payments and should be kept secure.
⚠️ Security Note: Never expose your API key in client-side code. Always make API calls from your server.
const PaymentGateway = require('@paymentgateway/sdk');
const client = new PaymentGateway({
apiKey: 'sk_test_your_api_key',
environment: 'production' // or 'sandbox'
});API Reference
Create Payment Intent
Creates a new payment intent to collect payment from a customer.
/v1/payment-intentsParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| amount | integer | Yes | Amount in cents |
| currency | string | Yes | Three-letter ISO currency code |
| customer | string | No | Customer ID |
| description | string | No | Description of the payment |
Example Request
const PaymentGateway = require('@paymentgateway/sdk');
const client = new PaymentGateway({
apiKey: 'sk_test_your_api_key',
environment: 'production'
});
const paymentIntent = await client.paymentIntents.create({
amount: 2000,
currency: 'usd',
customer: 'cus_123456',
description: 'Software subscription'
});
console.log(paymentIntent);Success Response
200 OK{
"id": "pi_1234567890",
"object": "payment_intent",
"amount": 2000,
"amount_received": 0,
"currency": "usd",
"status": "requires_payment_method",
"client_secret": "pi_1234567890_secret_abcdef",
"customer": "cus_123456",
"description": "Software subscription",
"payment_method": null,
"created": 1234567890,
"livemode": false,
"metadata": {},
"next_action": null,
"receipt_email": null,
"setup_future_usage": null
}Understanding Payment Intent Status
Confirm Payment Intent
Confirms a payment intent and attempts to process the payment.
/v1/payment-intents/:id/confirmExample Request
const confirmed = await client.paymentIntents.confirm(
'pi_1234567890',
{
payment_method: 'pm_card_visa'
}
);
console.log(confirmed);Create Customer
Creates a new customer object.
/v1/customersExample Request
const customer = await client.customers.create({
email: '[email protected]',
name: 'John Doe',
phone: '+1234567890',
metadata: {
user_id: '12345'
}
});
console.log(customer);List Payment Intents
Returns a list of payment intents. Results are paginated and can be filtered by customer or status.
/v1/payment-intentsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
| limit | integer | Number of results (1-100, default: 10) |
| starting_after | string | Cursor for pagination |
| customer | string | Filter by customer ID |
| status | string | Filter by status (succeeded, failed, pending) |
Example Request
const payments = await client.paymentIntents.list({
limit: 10,
customer: 'cus_123456',
status: 'succeeded'
});
console.log(payments.data);
console.log('Has more:', payments.has_more);Create Refund
Refunds a payment that has been previously created. Refunds can be partial or full.
/v1/refundsExample Request
const refund = await client.refunds.create({
payment_intent: 'pi_1234567890',
amount: 1000, // Partial refund of $10.00
reason: 'requested_by_customer'
});
console.log(refund);Create Subscription
Creates a subscription for recurring payments. Supports multiple pricing tiers and billing intervals.
/v1/subscriptionsParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| customer | string | Yes | Customer ID |
| price | string | Yes | Price ID |
| trial_days | integer | No | Free trial period in days |
| payment_method | string | No | Payment method ID |
Example Request
const subscription = await client.subscriptions.create({
customer: 'cus_123456',
price: 'price_monthly_pro',
trial_days: 14,
payment_method: 'pm_card_visa',
metadata: {
plan: 'pro',
source: 'website'
}
});
console.log(subscription);Pagination
All list endpoints return paginated results. Use the has_more field and starting_after parameter to iterate through pages.
Response Structure
{
"object": "list",
"data": [...],
"has_more": true,
"url": "/v1/payment-intents"
}Iterating Through Pages
let allPayments = [];
let hasMore = true;
let startingAfter = null;
while (hasMore) {
const response = await client.paymentIntents.list({
limit: 100,
starting_after: startingAfter
});
allPayments = allPayments.concat(response.data);
hasMore = response.has_more;
if (hasMore) {
startingAfter = response.data[response.data.length - 1].id;
}
}
console.log(`Total payments: ${allPayments.length}`);Complete Payment Flow
Understanding the Payment Process
Processing a payment involves multiple steps to ensure security and reliability. Here's the complete flow:
Create Payment Intent
POST /v1/payment-intentsInitialize a payment with amount and currency. This creates a payment intent in 'requires_payment_method' status.
Collect Payment Method
Client-side collectionSecurely collect card details from the customer using our client-side SDK or hosted payment page.
Confirm Payment
POST /v1/payment-intents/:id/confirmConfirm the payment intent with the payment method. Status changes to 'processing' then 'succeeded' or 'requires_action'.
Handle 3D Secure (if required)
next_action.redirect_to_urlIf the card requires authentication, redirect customer to complete 3D Secure verification.
Receive Webhook
payment_intent.succeededListen for 'payment_intent.succeeded' webhook to confirm payment completion on your server.
Fulfill Order
Your business logicOnce payment is confirmed, fulfill the order and send confirmation to customer.
✅ Successful Payment
🔐 3D Secure Required
❌ Payment Declined
⏳ Async Payment
Error Responses
All errors return a consistent JSON structure with detailed information to help you debug issues.
Error Response Format
{
"error": {
"type": "card_error",
"code": "card_declined",
"message": "Your card was declined.",
"decline_code": "insufficient_funds",
"param": "payment_method",
"charge": "ch_1234567890"
}
}card_error402Card was declined
{
"error": {
"type": "card_error",
"code": "card_declined",
"decline_code": "insufficient_funds",
"message": "Your card has insufficient funds."
}
}- •Insufficient funds
- •Expired card
- •Incorrect CVC
- •Card reported lost/stolen
invalid_request_error400Invalid parameters
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid_integer",
"message": "Invalid integer: abc",
"param": "amount"
}
}- •Missing required parameter
- •Invalid parameter type
- •Parameter out of range
- •Invalid currency code
authentication_error401Authentication failed
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "Invalid API Key provided."
}
}- •Invalid API key
- •Expired API key
- •API key for wrong environment
- •Missing API key
rate_limit_error429Too many requests
{
"error": {
"type": "rate_limit_error",
"message": "Too many requests. Please try again later."
}
}- •Exceeded rate limit
- •Too many concurrent requests
- •Burst limit exceeded
Handling Errors in Your Code
try {
const payment = await client.paymentIntents.create({
amount: 2000,
currency: 'usd'
});
console.log('Payment created:', payment.id);
} catch (error) {
if (error.type === 'card_error') {
// Card was declined
console.error('Card declined:', error.decline_code);
// Show user-friendly message
} else if (error.type === 'invalid_request_error') {
// Invalid parameters
console.error('Invalid request:', error.message);
} else if (error.type === 'authentication_error') {
// Authentication failed
console.error('Auth error:', error.message);
} else {
// Other error
console.error('Unexpected error:', error);
}
}Webhooks
Why Use Webhooks?
Webhooks provide real-time notifications about events in your account. Instead of polling our API, we'll push updates to your server immediately when events occur. This is essential for:
Setting Up Webhooks
https://yourdomain.com/webhooksWebhook Event Types
Payment Intents
payment_intent.createdPayment intent createdpayment_intent.succeededPayment completed successfullypayment_intent.failedPayment attempt failedpayment_intent.canceledPayment was canceledpayment_intent.processingPayment is processingCustomers
customer.createdNew customer createdcustomer.updatedCustomer details updatedcustomer.deletedCustomer was deletedSubscriptions
subscription.createdNew subscription startedsubscription.updatedSubscription modifiedsubscription.deletedSubscription canceledsubscription.trial_will_endTrial ending in 3 daysRefunds
refund.createdRefund initiatedrefund.updatedRefund status changedrefund.failedRefund failedWebhook Payload Structure
All webhook events follow a consistent structure with the event type, data object, and metadata.
{
"id": "evt_1234567890",
"object": "event",
"type": "payment_intent.succeeded",
"created": 1234567890,
"livemode": false,
"data": {
"object": {
"id": "pi_1234567890",
"object": "payment_intent",
"amount": 2000,
"currency": "usd",
"status": "succeeded",
"customer": "cus_123456",
"description": "Software subscription",
"metadata": {
"order_id": "12345",
"user_id": "67890"
}
}
},
"pending_webhooks": 1,
"request": {
"id": "req_1234567890",
"idempotency_key": "unique-key-123"
}
}🔐 Signature Verification
Critical: Always verify webhook signatures to ensure requests are from our servers and haven't been tampered with.
Implementation
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express endpoint
app.post('/webhooks', express.raw({type: 'application/json'}), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const webhookSecret = process.env.WEBHOOK_SECRET;
if (!verifyWebhookSignature(req.body, signature, webhookSecret)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
switch (event.type) {
case 'payment_intent.succeeded':
console.log('Payment succeeded:', event.data.object.id);
// Fulfill order
break;
case 'payment_intent.failed':
console.log('Payment failed:', event.data.object.id);
// Notify customer
break;
}
res.json({received: true});
});Webhook Best Practices
Rate Limiting
Response Headers
Error Handling
card_error402Card was declined
invalid_request_error400Invalid parameters
authentication_error401Authentication failed
rate_limit_error429Too many requests
SDK Features
Type Safety
Full TypeScript support with auto-completion
Automatic Retries
Built-in retry logic for failed requests
Idempotency
Prevent duplicate operations automatically
Webhook Verification
Secure webhook signature validation
Pagination
Easy iteration through large result sets
Error Handling
Detailed error messages and types
Testing
Test Mode
Use test API keys (starting with sk_test_) to test your integration without processing real payments.
Idempotency
Prevent duplicate operations by including an idempotency key in your requests.
const payment = await client.paymentIntents.create({
amount: 2000,
currency: 'usd'
}, {
idempotencyKey: 'unique-key-123'
});Best Practices
Use Webhooks
Don't poll for payment status. Use webhooks for real-time notifications.
Handle Errors
Implement proper error handling and retry logic for failed requests.
Secure API Keys
Never expose API keys in client-side code. Use environment variables.
Log Requests
Log all API requests and responses for debugging and auditing.
Use Metadata
Store custom data in metadata fields for easier tracking and reporting.
Test Thoroughly
Test all payment flows in test mode before going live.
Performance Optimization
Optimization Tips
Note: This is a sample API documentation demonstrating our technical writing capabilities. We can create comprehensive, interactive documentation tailored to your API specifications.
