Payment API: A Technical Integration Guide for Developers
Explore our comprehensive technical guide to integrating a payment API. Aimed at developers, this tutorial covers everything from authentication to error handling for a smooth and secure integration.
12 min read

Table of contents
The Backbone of Your Business
In the digital economy, a payment API isn't just a feature; it's the transactional heart of your business. A successful integration ensures a smooth user experience, accurate financial reconciliation, and rock-solid security. However, the path to integration is fraught with technical challenges: authentication, state management, data security, fraud prevention, and more.
For businesses operating in high-risk sectors, these challenges are amplified. A single mistake can lead to financial losses, account suspension, or reputational damage. That's why a deep understanding of a payment API's mechanics is not just desirable: it's absolutely essential.
According to a study by the Baymard Institute, 17% of cart abandonments are due to a checkout process that is too long or complicated. An optimized API integration can significantly reduce this figure.
This technical guide is designed for you: developers, CTOs, and technical architects. We will dissect, step by step, the process of integrating a modern RESTful payment API like Bridge Pay's. From obtaining your API keys to handling webhooks and errors, you will have everything you need for a robust, secure, and high-performing integration.
1. Prerequisites: Preparing the Groundwork
Before diving into code and endpoints, careful preparation is essential to ensure a smooth integration. Think of this phase as the foundation of your project. You will need the following:
- Access to a Sandbox Environment: A testing environment is crucial. It allows you to experiment without risking real money. Bridge Pay provides a comprehensive Sandbox environment that simulates 99% of production features.
- Your API Keys: After creating your test account, you will get two essential keys: a public key (usable on the client-side, e.g.,
pk_test_...) and a secret key (to be kept on your server, e.g.,sk_test_...). Never expose your secret key publicly. - Basic Knowledge of HTTP/REST: A firm grasp of REST concepts (endpoints, GET/POST methods, headers, JSON) is fundamental.
- An API Testing Tool: Tools like Postman or cURL commands are perfect for making your first calls and inspecting the API's responses.
2. Detailed Integration Steps
Step 1: Understanding REST Architecture and Authentication
Modern payment APIs, including Bridge Pay's, are based on the principles of REST (Representational State Transfer) architecture. This means you will interact with resources (payments, customers, refunds) via predictable URLs and standard HTTP methods (GET, POST, PUT, DELETE).
Authentication is the first gate to pass. Every request you send to the API must be authenticated to prove your identity. The Bridge Pay API uses the Bearer Token authentication scheme. You must include your secret API key in the Authorization header of every request. Any request made without authentication or with an invalid key will return a 401 Unauthorized error.
Example of an authenticated request with cURL:
curl https://api.bridgepay.io/v1/balance \
-H "Authorization: Bearer sk_test_YOUR_SECRET_KEY"
The distinction between public and secret keys is vital. The public key is used in your front-end code (JavaScript in the browser) for non-sensitive operations like credit card tokenization. The secret key must never leave your server. It is used for critical calls: creating a payment, issuing a refund, etc.
Step 2: Creating a Payment (Charge)
The core of the integration is creating a payment. This is typically done via a POST request to an endpoint like /v1/charges. This request sends the transaction details to the payment API for processing.
The request body (payload) is a JSON object containing the essential information. Here is a typical example to create a payment of €99.99:
{
"amount": 9999, // Amount in cents
"currency": "eur", // ISO currency code
"source": "tok_1Lq...", // Token representing the card, obtained on the client-side
"description": "Order #12345 - Limited edition T-shirt",
"metadata": {
"customer_id": "cust_abc123",
"order_id": "order_xyz789"
}
}
A few important points to note:
amount: The amount is almost always an integer representing the smallest unit of the currency (cents for EUR/USD) to avoid floating-point issues.source: Never handle raw credit card details on your server (PCI-DSS non-compliance). Instead, use a front-end library (like Bridge.js) to convert card details into a secure token (tok_...). This is the token you use in the API call.metadata: This is a valuable space for storing internal references (customer ID, order ID). This data will be useful for reconciliation and tracking.
A successful request will return a 200 OK code and a complete JSON object representing the payment, including its unique ID (ch_...), its status (succeeded, failed), and other details.
Step 3: Handling Idempotency to Avoid Duplicate Charges
Imagine a customer clicks "Pay," your server sends the request to the payment API, but the network connection is lost before the response is received. What happened? Was the payment processed? If you resend the same request, do you risk charging the customer twice? This is where idempotency comes in.
An idempotent operation, if repeated, produces the same result with no side effects. To ensure this, modern payment APIs allow you to pass a unique idempotency key in your request header, for example, Idempotency-Key.
curl https://api.bridgepay.io/v1/charges \
-H "Authorization: Bearer sk_test_..." \
-H "Idempotency-Key: your-transaction-uuid-12345" \
-d amount=1000 -d currency=eur -d source=tok_...
How does it work?
- On the first request with an idempotency key, the Bridge Pay server processes the request and stores the result, associating it with that key.
- If you send a second request with the same idempotency key (within 24 hours, for example), the server will not re-process the request. It will simply return the response from the original request.
This is an essential safeguard for building a reliable payment system. The best practice is to generate a unique key (like a v4 UUID) on the server-side for each user-initiated operation that could result in a charge.
Step 4: Using Webhooks for Asynchronous Notifications
Payment processing is not always instantaneous. A card payment might be authorized immediately, but a bank transfer can take days. You cannot leave an HTTP request open while waiting for confirmation. The solution is the webhook.
A webhook is a "callback" mechanism. You provide Bridge Pay with a URL on your server. When an important event occurs in your account (e.g., a payment succeeds, a dispute is opened, a refund is processed), the Bridge Pay API will send a POST request to your URL with the event details.
Steps to set up webhooks:
- Create an endpoint on your server: Develop a new endpoint (e.g.,
https://your-site.com/webhooks/bridgepay) that can receive POST requests with a JSON body. - Register the URL in your Bridge Pay dashboard: Go to the "Developers" > "Webhooks" section of your dashboard and add your URL.
- Process the event: Your code should parse the JSON body of the request, identify the event type (
charge.succeeded,dispute.created, etc.), and act accordingly (update the order to "paid," send a confirmation email, etc.).
Security First: Anyone could call your webhook endpoint. To ensure the request genuinely comes from Bridge Pay, you must verify the webhook's signature. Bridge Pay signs each event with a shared secret key. Your endpoint must calculate the signature from the request body and compare it to the one provided in the Bridge-Signature header. If they don't match, ignore the request.
Step 5: Comprehensive Error Handling
Even with the best integration, errors will happen. A card might be expired, funds may be insufficient, or a fraud rule could be triggered. Robust error handling is what separates an amateur integration from a professional one. The Bridge Pay API uses standard HTTP status codes to indicate the success or failure of a request.
Table of Common Errors:
| HTTP Code | Error Type | Meaning and Action |
|---|---|---|
200 OK |
Success | Everything went well. |
400 Bad Request |
Invalid Parameters | The request is malformed (e.g., invalid amount, unknown currency). The response body will contain more details. Do not retry without correcting the request. |
401 Unauthorized |
Authentication Error | Your API key is incorrect or missing. Check your credentials. |
402 Payment Required |
Payment Failure | The card was declined by the issuing bank. The decline_code in the response gives the reason (insufficient funds, suspected fraud...). Prompt the user to use a different payment method. |
429 Too Many Requests |
Rate Limiting | You have sent too many requests in a short period of time. Reduce your call frequency. |
5xx |
Server Error | An issue occurred on Bridge Pay's end. These errors are rare. Implement a retry policy with exponential backoff. |
Your code must be able to parse both the HTTP status code and the error response body to act appropriately, whether it's by displaying a clear message to the user or triggering an alert for your technical team.
3. Complete Code Example (Python)
Here is a Python example that illustrates creating a charge with an idempotency key. It uses the popular requests library.
import requests
import uuid
# Your keys (store securely, e.g., as environment variables)
BRIDGE_API_KEY = "sk_test_YOUR_SECRET_KEY"
# The Bridge Pay API URL
API_URL = "https://api.bridgepay.io/v1/charges"
# Generate a unique idempotency key for this transaction
IDEMPOTENCY_KEY = str(uuid.uuid4())
# The transaction payload
charge_data = {
"amount": 2500, # 25.00 EUR
"currency": "eur",
"source": "tok_...", # Obtained from the front-end
"description": "Payment for order XYZ_123"
}
# The request headers, including authentication and idempotency
headers = {
"Authorization": f"Bearer {BRIDGE_API_KEY}",
"Content-Type": "application/json",
"Idempotency-Key": IDEMPOTENCY_KEY
}
try:
# Make the POST request
response = requests.post(API_URL, json=charge_data, headers=headers, timeout=10)
# Raises an exception for 4xx/5xx error codes
response.raise_for_status()
# If the request is successful
payment_response = response.json()
print("Payment successful!")
print(f"Payment ID: {payment_response.get('id')}")
print(f"Status: {payment_response.get('status')}")
except requests.exceptions.HTTPError as err:
print(f"An HTTP error occurred: {err}")
# Parse the error response body for more details
error_details = err.response.json()
print(f"Error details: {error_details.get('error', {}).get('message')}")
except requests.exceptions.RequestException as err:
print(f"A network or connection error occurred: {err}")
4. Verification: How to Know If It's Working
The integration is complete, but how can you be sure everything is working as expected? Here is a quick verification checklist:
- The Bridge Pay Dashboard: This is your source of truth. After making a test payment, log in to your Sandbox dashboard. The payment should appear there instantly, with the correct amount, description, and metadata.
- Successful API Response (
200 OK): Ensure your back-end code receives a200status code and a valid payment JSON object after a successful payment attempt. - Webhook Event Received: Check your server logs. Your webhook endpoint should have received an event (e.g.,
charge.succeeded) and processed it correctly (for example, by updating a database). The Bridge Pay dashboard provides a log of webhook delivery attempts, which is very useful for debugging. - Confirmation Email: If your post-payment logic includes sending an email, make sure it was sent and received correctly.
5. Troubleshooting: Common Problems and Solutions
Even the most seasoned developers run into obstacles. Here is a list of the most common problems and how to solve them.
Problem: 401 Unauthorized Error
This is the easiest error to fix. It means your API key is invalid or missing. Make sure that:
- You are using your secret key (sk_test_...) and not your public key (pk_test_...).
- The key has not been revoked or regenerated.
- You are including it correctly in the Authorization header with the Bearer prefix (note the space after "Bearer").
- You are using the correct key for the correct environment (test key for Sandbox, live key for production).
Problem: My Webhook Endpoint Isn't Receiving Anything
There are several possible causes:
1. Accessibility: Your endpoint must be a public URL accessible from the internet. A localhost URL will not work. Use a service like ngrok during development to securely expose your local environment to the web.
2. Your Endpoint's Response: Your endpoint must respond to the webhook request with a 200 OK status code as quickly as possible. If Bridge Pay receives another code (or a timeout), it will consider the delivery a failure and retry several times before giving up.
Problem: 400 Bad Request Error with an Invalid amount Message
This error indicates that the amount format is incorrect. Remember that most payment APIs require the amount to be an integer representing cents (or the smallest unit of the currency). If you want to charge €50.25, the amount must be 5025. Never send a floating-point number for the amount.
Ready to Integrate?
You now have a complete technical overview of payment API integration. By following these steps and best practices, you are equipped to build a payment system that is not only functional but also robust, secure, and scalable.
The Bridge Pay API was designed to simplify these complexities, especially for businesses in regulated or high-risk sectors, by offering clear tools and exhaustive documentation.
Ready to get started? Explore our comprehensive documentation for detailed language-specific guides, interactive API references, and to create your free sandbox account.


