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/publicAuthentication
The Payment API uses two different authentication methods depending on the endpoint:- API Key (Server-to-Server)
- Client Secret (Browser)
Use for: Payment processing from your backend serverEndpoints 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
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/authorizeinteger
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"}Error Responses
Error Responses
400 Bad Request - Invalid Amount400 Bad Request - Unsupported Currency402 Payment Required - Card Declined402 Payment Required - Fraud Declined409 Conflict - Idempotency Key Mismatch429 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/saleWhen to use Sale vs Authorize:Use Sale when:
- Immediate charge is required (subscriptions, digital goods)
- You ship goods immediately
- Payment and fulfillment happen together
- 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/capturestring
required
Payment ID from authorization response
integer
required
Amount to capture in centsMust be: ≤ authorized amountPartial captures: Allowed (e.g., capture 100 authorization)
Error Responses
Error Responses
400 Bad Request - Already Captured400 Bad Request - Amount Too High400 Bad Request - Authorization Expired404 Not Found
Void Payment
endpoint
/api/v1/payments/:id/voidstring
required
Payment ID to void
string
required
Reason for voiding (for audit logs)Example: “Customer requested cancellation”, “Order canceled”
Error Responses
Error Responses
400 Bad Request - Already Captured400 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: Return money after capture (money has been charged)
Refund Payment
endpoint
/api/v1/payments/:id/refundstring
required
Payment ID to refund
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”
Error Responses
Error Responses
400 Bad Request - Not Captured400 Bad Request - Amount Too High400 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/:idstring
required
Payment ID
Error Responses
Error Responses
404 Not Found401 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-intentscheckout_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 IDstring
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), manualautomatic: Funds captured immediately after authorizationmanual: You must manually capture later
string
Customer email (pre-filled on checkout page)
object
Custom metadata
Next Steps:
- Redirect your customer to
checkout_url - Customer completes payment on hosted page
- Customer is redirected to your
success_urlwith?payment_intent=pi_abc123... - Verify payment status on your server
Get Payment Intent (Public)
endpoint
/api/public/payment-intents/:idstring
required
Payment intent ID
Confirm Payment Intent
endpoint
/api/public/payment-intents/:id/confirmstring
required
Payment intent ID
string
required
Client secret from payment intent creationAlternative:
?client_secret=pi_abc123_secret_xyz789object
required
Card details
string
Customer email (optional if provided during intent creation)
Error Responses
Error Responses
401 Unauthorized - Invalid Client Secret410 Gone - Intent Expired402 Payment Required - Card Declined410 Gone - Max Attempts
Cancel Payment Intent
endpoint
/api/v1/payment-intents/:id/cancelstring
required
Payment intent ID to cancel
Error Responses
Error Responses
400 Bad Request - Already Completed
Transaction Endpoints
Get Transaction
endpoint
/api/v1/transactions/:idstring
required
Transaction ID
List Transactions
endpoint
/api/v1/transactionsstring
Filter by statusValues:
authorized, captured, voided, refunded, failedinteger
Number of results per pageDefault: 10Max: 100
integer
Number of results to skipDefault: 0
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
created
created
Payment Intent StatusPayment intent created but no payment attempt yet.Next actions: Confirm payment intent, Cancel
captured
captured
Payment completedFunds have been charged to the customer’s card.Next actions: Refund
voided
voided
Authorization canceledHold released on customer’s card. No money was charged.Final state - No further actions possible
refunded
refunded
Fully refundedAll captured funds returned to customer.Final state - No further actions possible
partially_refunded
partially_refunded
Partially refundedSome funds returned to customer, remaining amount still captured.Next actions: Additional refunds (up to remaining amount)
failed
failed
Payment failedAuthorization attempt declined by issuer or fraud system.Final state - Create new payment for retry
expired
expired
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 header2
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
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]