Skip to main content

Payment API Service

The Payment API Service is the main gateway for processing payments. It orchestrates card tokenization, fraud detection, and transaction processing while providing a simple REST API for merchants.
Base URL: https://paymentgateway.redahaloubi.com/api/v1Public API: https://paymentgateway.redahaloubi.com/api/public

Authentication

The Payment API uses two different authentication methods depending on the endpoint:
Use for: Payment processing from your backend server
Endpoints requiring API Key:
  • /api/v1/payments/* - All payment operations
  • /api/v1/transactions/* - Transaction queries
  • /api/v1/payment-intents - Create payment intent
  • /api/v1/payment-intents/:id/cancel - Cancel payment intent
How to get an API key: See Merchant API → Create API Key

Rate Limits

Payment Operations

20 requests per second per merchant10,000 requests per hour per merchant

Transaction Queries

100 requests per second per merchant

Public Endpoints

50 requests per second per IPUsed for hosted checkout page

Idempotency Cache

24 hour cache durationPrevents duplicate payments

Payment Flow Overview


Payment Operations

Authorize Payment

endpoint
/api/v1/payments/authorize
Authorize a payment by holding funds on the customer’s card without charging. Authorization is valid for 7 days. Authentication: API Key required Request Body
integer
required
Amount in cents (e.g., 9999 = $99.99)Min: 1 (0.01 in currency)Max: No limit (dependent on card)
string
required
Three-letter currency codeSupported: USD, EUR, MADLength: Exactly 3 characters
object
required
Card details
object
Customer information (optional)
string
Payment description (e.g., “Order #12345”)
object
Custom key-value pairs for your referenceExample: {"order_id": "12345", "customer_id": "cus_abc"}
Example Request
Response (200 OK)
400 Bad Request - Invalid Amount
400 Bad Request - Unsupported Currency
402 Payment Required - Card Declined
402 Payment Required - Fraud Declined
409 Conflict - Idempotency Key Mismatch
429 Too Many Requests
Idempotency: Include an Idempotency-Key header to safely retry requests. If the same key is used within 24 hours, the original response is returned without creating a new payment.

Sale Payment

endpoint
/api/v1/payments/sale
Process a sale (authorize + capture in one step). Funds are immediately charged to the customer’s card. Authentication: API Key required Request Body Same as Authorize Payment Example Request
Response (200 OK)
When to use Sale vs Authorize:Use Sale when:
  • Immediate charge is required (subscriptions, digital goods)
  • You ship goods immediately
  • Payment and fulfillment happen together
Use Authorize when:
  • You need to verify funds availability first
  • You ship physical goods later
  • You need to adjust the amount before capture
  • You want to manually review orders

Capture Payment

endpoint
/api/v1/payments/:id/capture
Capture a previously authorized payment. You can capture the full amount or a partial amount. Authentication: API Key required Path Parameters
string
required
Payment ID from authorization response
Request Body
integer
required
Amount to capture in centsMust be: ≤ authorized amountPartial captures: Allowed (e.g., capture 50of50 of 100 authorization)
Example Request
Response (200 OK)
400 Bad Request - Already Captured
400 Bad Request - Amount Too High
400 Bad Request - Authorization Expired
404 Not Found
Capture Deadline: Authorizations expire after 7 days. Capture before the expiration date or the authorization will be automatically voided.

Void Payment

endpoint
/api/v1/payments/:id/void
Cancel an authorized payment before it’s captured. This releases the hold on the customer’s card. Authentication: API Key required Path Parameters
string
required
Payment ID to void
Request Body
string
required
Reason for voiding (for audit logs)Example: “Customer requested cancellation”, “Order canceled”
Example Request
Response (200 OK)
400 Bad Request - Already Captured
400 Bad Request - Already Voided
Void vs Refund:Void: Cancel before capture (no money has been charged)
Refund: Return money after capture (money has been charged)

Refund Payment

endpoint
/api/v1/payments/:id/refund
Refund a captured payment. Supports full and partial refunds. Authentication: API Key required Path Parameters
string
required
Payment ID to refund
Request Body
integer
required
Amount to refund in centsFull refund: Original payment amountPartial refund: Less than original amount
string
required
Refund reason (for audit logs)Example: “Product returned”, “Service not delivered”
Example Request
Response (200 OK)
400 Bad Request - Not Captured
400 Bad Request - Amount Too High
400 Bad Request - Already Refunded
Refund Processing:
  • Refunds are processed immediately
  • Funds typically appear in customer’s account within 5-10 business days
  • Multiple partial refunds are supported until full amount is refunded

Get Payment

endpoint
/api/v1/payments/:id
Retrieve details of a specific payment. Authentication: API Key required Path Parameters
string
required
Payment ID
Example Request
Response (200 OK)
404 Not Found
401 Unauthorized - Wrong Merchant

Payment Intents

Payment Intents provide a hosted checkout solution where customers complete payment in a browser.

Create Payment Intent

endpoint
/api/v1/payment-intents
Create a payment intent for hosted checkout. Returns a checkout_url to redirect your customer. Authentication: API Key required Request Body
integer
required
Amount in cents
string
required
Currency code (USD, EUR, MAD)
string
required
URL to redirect after successful paymentMust be HTTPS (except localhost for testing)Supports placeholders: {CHECKOUT_SESSION_ID} will be replaced with payment intent ID
string
URL to redirect if customer cancelsDefault: Same as success_url
string
Your internal order ID
string
Payment description shown to customer
string
When to capture fundsValues: automatic (default), manual
  • automatic: Funds captured immediately after authorization
  • manual: You must manually capture later
string
Customer email (pre-filled on checkout page)
object
Custom metadata
Example Request
Response (201 Created)
Next Steps:
  1. Redirect your customer to checkout_url
  2. Customer completes payment on hosted page
  3. Customer is redirected to your success_url with ?payment_intent=pi_abc123...
  4. Verify payment status on your server

Get Payment Intent (Public)

endpoint
/api/public/payment-intents/:id
Get payment intent details (browser-safe, no sensitive data returned). Authentication: None required (public endpoint) Path Parameters
string
required
Payment intent ID
Example Request
Response (200 OK)
Security Note: This endpoint does NOT return client_secret. It only provides public information needed to display the checkout page.

Confirm Payment Intent

endpoint
/api/public/payment-intents/:id/confirm
Confirm a payment intent by submitting card details. This processes the actual payment. Authentication: Client Secret required (in header or query) Path Parameters
string
required
Payment intent ID
Headers or Query
string
required
Client secret from payment intent creationAlternative: ?client_secret=pi_abc123_secret_xyz789
Request Body
object
required
Card details
string
Customer email (optional if provided during intent creation)
Example Request
Response (200 OK)
401 Unauthorized - Invalid Client Secret
410 Gone - Intent Expired
402 Payment Required - Card Declined
410 Gone - Max Attempts
Payment Attempt Limits:
  • Maximum 5 attempts per payment intent
  • Each failed attempt is tracked
  • After 5 failures, the intent is locked
  • Create a new payment intent for additional attempts

Cancel Payment Intent

endpoint
/api/v1/payment-intents/:id/cancel
Cancel a payment intent before it’s completed. Authentication: API Key required Path Parameters
string
required
Payment intent ID to cancel
Example Request
Response (200 OK)
400 Bad Request - Already Completed

Transaction Endpoints

Get Transaction

endpoint
/api/v1/transactions/:id
Get details of a specific transaction. Authentication: API Key required Path Parameters
string
required
Transaction ID
Example Request
Response (200 OK)

List Transactions

endpoint
/api/v1/transactions
List all transactions for your merchant account. Authentication: API Key required Query Parameters
string
Filter by statusValues: authorized, captured, voided, refunded, failed
integer
Number of results per pageDefault: 10Max: 100
integer
Number of results to skipDefault: 0
Example Request
Response (200 OK)

Test Cards

Use these test card numbers for development and testing:

✅ Visa - Approved

Card Number: 4242 4242 4242 4242Expiry: Any future date (e.g., 12/2027)CVV: Any 3 digits (e.g., 123)Result: Authorization approved

✅ Mastercard - Approved

Card Number: 5555 5555 5555 4444Expiry: Any future dateCVV: Any 3 digitsResult: Authorization approved

❌ Generic Decline

Card Number: 4000 0000 0000 0002Expiry: Any future dateCVV: Any 3 digitsResult: Declined (code 05 - Do not honor)

❌ Insufficient Funds

Card Number: 4000 0000 0000 9995Expiry: Any future dateCVV: Any 3 digitsResult: Declined (code 51)

❌ Expired Card

Card Number: 4000 0000 0000 0069Expiry: Any future dateCVV: Any 3 digitsResult: Declined (code 54)

❌ CVV Mismatch

Card Number: 4000 0000 0000 0127Expiry: Any future dateCVV: Any 3 digitsResult: Declined (code N7)

❌ Processing Error

Card Number: 4000 0000 0000 0119Expiry: Any future dateCVV: Any 3 digitsResult: Declined (code 96)

⚠️ High Fraud Risk

Card Number: 4000 0000 0000 0259Expiry: Any future dateCVV: Any 3 digitsResult: Declined (fraud score > 70)
Test Card Rules:
  • All test cards use the same validation rules as real cards
  • Use any valid future expiry date (e.g., 12/2027)
  • Use any 3-digit CVV (except for CVV mismatch test)
  • Cardholder name can be anything
  • No real money is charged

Payment Status Lifecycle

Status Descriptions

Payment Intent StatusPayment intent created but no payment attempt yet.Next actions: Confirm payment intent, Cancel
Funds held on customer’s cardAuthorization is valid for 7 days. No money has been charged yet.Next actions: Capture, Void
Payment completedFunds have been charged to the customer’s card.Next actions: Refund
Authorization canceledHold released on customer’s card. No money was charged.Final state - No further actions possible
Fully refundedAll captured funds returned to customer.Final state - No further actions possible
Partially refundedSome funds returned to customer, remaining amount still captured.Next actions: Additional refunds (up to remaining amount)
Payment failedAuthorization attempt declined by issuer or fraud system.Final state - Create new payment for retry
Authorization expiredAuthorization not captured within 7 days. Automatically voided.Final state - Create new payment for retry

Error Codes

Bad Request
Invalid request format or validation errorCommon causes:
  • Missing required fields
  • Invalid amount (must be positive integer)
  • Unsupported currency
  • Invalid card format
Unauthorized
Authentication failedCommon causes:
  • Missing API key or client secret
  • Invalid API key
  • Expired client secret
  • API key from different merchant
Payment Required
Payment declinedCommon causes:
  • Card declined by issuer (insufficient funds, expired, etc.)
  • Fraud risk too high
  • CVV verification failed
  • Card reported lost/stolen
Not Found
Resource not foundCommon causes:
  • Invalid payment ID
  • Invalid transaction ID
  • Payment belongs to different merchant
Conflict
Request conflicts with current stateCommon causes:
  • Idempotency key already used with different data
  • Payment already captured/voided/refunded
  • Cannot perform action in current status
Gone
Resource expired or no longer availableCommon causes:
  • Payment intent expired (1 hour)
  • Authorization expired (7 days)
  • Maximum payment attempts reached
Too Many Requests
Rate limit exceededLimits:
  • Payments: 20/sec, 10,000/hour
  • Transactions: 100/sec
  • Public endpoints: 50/sec per IP

Idempotency

Idempotency prevents duplicate payments caused by network retries or accidental double-clicks.

How It Works

1

Include Idempotency Key

Send a unique key in the Idempotency-Key header
2

First Request Processed

The payment is processed normally and response is cached for 24 hours
3

Duplicate Requests Return Cached Response

If the same key is used again within 24 hours with the same request body, the original response is returned immediately without creating a new payment
4

Different Request Body = Error

If the same key is used with a different request body, you’ll get a 409 Conflict error

Best Practices

Use Unique Keys

Include order ID, user ID, timestamp, or attempt numberExample: order-{order_id}-{attempt}

Consistent Keys

Use the same key for all retry attempts of the same payment

24-Hour Expiry

Keys expire after 24 hours. After expiry, a new payment will be created

Test Retries

Test your retry logic in development to ensure proper idempotency handling

Webhooks

Payment API sends webhooks for payment events to keep your server updated in real-time.

Webhook Events

payment.authorized

Payment authorized successfully

payment.captured

Payment captured (charged)

payment.voided

Payment voided (canceled)

payment.refunded

Payment refunded (full or partial)

payment.failed

Payment authorization failed

payment_intent.created

Payment intent created

payment_intent.succeeded

Payment intent completed successfully

payment_intent.canceled

Payment intent canceled

Webhook Payload

Verifying Webhook Signatures

Always verify webhook signatures to ensure requests are from Payment Gateway.

Webhook Retry Logic

1

Initial Delivery

Webhook sent immediately after event
2

Retry Schedule

If delivery fails (non-200 response):
  • 1st retry: After 5 minutes
  • 2nd retry: After 15 minutes
  • 3rd retry: After 1 hour
  • 4th retry: After 6 hours
3

Maximum Attempts

After 5 failed attempts, webhook is marked as failed
4

Expiration

Webhooks expire after 24 hours

Next Steps

Quick Start

Create your first payment intent in 5 minutes

Merchant API

Manage merchant accounts and team members

Checkout Integration

Build a custom checkout flow

CLI Tool

Test payments from the command line

Questions? Contact support at [email protected]