Jiffoo Docs

Payments API

Complete guide to payment processing in Jiffoo Mall

Payments API

Process payments securely using multiple payment methods including credit cards, digital wallets, and bank transfers.

Payment Flow

sequenceDiagram
    Client->>API: POST /payments/initiate
    API->>Payment Provider: Create payment intent
    Payment Provider->>API: Return payment details
    API->>Client: Return payment session
    Client->>Payment Provider: Complete payment
    Payment Provider->>API: POST /payments/webhooks (webhook)
    API->>API: Update order status
    API->>Payment Provider: Acknowledge webhook
    Client->>API: GET /payments/:id (check status)
    API->>Client: Return payment status

Endpoints

Initiate Payment

Create a new payment session for an order.

Endpoint: POST /payments/initiate

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Request Body:

{
  "orderId": "order_abc123",
  "paymentMethodId": "pm_card_visa",
  "amount": 185.97,
  "currency": "USD",
  "returnUrl": "https://example.com/payment/success",
  "cancelUrl": "https://example.com/payment/cancel"
}

Response: 201 Created

{
  "success": true,
  "message": "Payment initiated",
  "data": {
    "paymentId": "pay_xyz789",
    "orderId": "order_abc123",
    "status": "pending",
    "amount": 185.97,
    "currency": "USD",
    "paymentMethod": {
      "id": "pm_card_visa",
      "type": "card",
      "brand": "visa",
      "last4": "4242"
    },
    "clientSecret": "pi_secret_abc123xyz789",
    "paymentUrl": "https://payment-provider.com/checkout/xyz789",
    "expiresAt": "2024-01-01T01:00:00.000Z",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}

Error Response: 400 Bad Request

{
  "success": false,
  "error": {
    "code": "INVALID_ORDER",
    "message": "Order not found or already paid"
  }
}

Validation Rules:

  • orderId: Required, must be a valid unpaid order
  • paymentMethodId: Required, must be a valid payment method
  • amount: Required, must match order total
  • currency: Required, ISO 4217 currency code
  • returnUrl: Required, valid URL
  • cancelUrl: Required, valid URL

Get Payment Details

Retrieve information about a specific payment.

Endpoint: GET /payments/:id

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Path Parameters:

  • id: Payment ID

Response: 200 OK

{
  "success": true,
  "data": {
    "id": "pay_xyz789",
    "orderId": "order_abc123",
    "status": "succeeded",
    "amount": 185.97,
    "currency": "USD",
    "paymentMethod": {
      "id": "pm_card_visa",
      "type": "card",
      "brand": "visa",
      "last4": "4242"
    },
    "transactionId": "txn_abc123xyz789",
    "receiptUrl": "https://payment-provider.com/receipts/xyz789",
    "refunded": false,
    "refundedAmount": 0,
    "metadata": {
      "customerIp": "192.168.1.1",
      "userAgent": "Mozilla/5.0..."
    },
    "createdAt": "2024-01-01T00:00:00.000Z",
    "completedAt": "2024-01-01T00:05:00.000Z"
  }
}

Error Response: 404 Not Found

{
  "success": false,
  "error": {
    "code": "PAYMENT_NOT_FOUND",
    "message": "Payment not found"
  }
}

Confirm Payment

Confirm a payment after user authorization.

Endpoint: POST /payments/:id/confirm

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Path Parameters:

  • id: Payment ID

Request Body:

{
  "paymentIntentId": "pi_abc123xyz789",
  "paymentMethodDetails": {
    "type": "card",
    "cardToken": "tok_visa_4242"
  }
}

Response: 200 OK

{
  "success": true,
  "message": "Payment confirmed",
  "data": {
    "id": "pay_xyz789",
    "orderId": "order_abc123",
    "status": "succeeded",
    "amount": 185.97,
    "currency": "USD",
    "transactionId": "txn_abc123xyz789",
    "receiptUrl": "https://payment-provider.com/receipts/xyz789",
    "completedAt": "2024-01-01T00:05:00.000Z"
  }
}

Error Response: 400 Bad Request

{
  "success": false,
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "Payment declined by card issuer",
    "details": {
      "declineCode": "insufficient_funds",
      "declineMessage": "Insufficient funds"
    }
  }
}

Get Payment Methods

Retrieve available payment methods for the user.

Endpoint: GET /payments/methods

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Response: 200 OK

{
  "success": true,
  "data": {
    "methods": [
      {
        "id": "pm_card_visa_1",
        "type": "card",
        "brand": "visa",
        "last4": "4242",
        "expiryMonth": 12,
        "expiryYear": 2025,
        "isDefault": true,
        "billingAddress": {
          "name": "John Doe",
          "city": "New York",
          "country": "US",
          "zipCode": "10001"
        }
      },
      {
        "id": "pm_card_mastercard_1",
        "type": "card",
        "brand": "mastercard",
        "last4": "5555",
        "expiryMonth": 6,
        "expiryYear": 2026,
        "isDefault": false
      },
      {
        "id": "pm_wallet_paypal",
        "type": "digital_wallet",
        "provider": "paypal",
        "email": "[email protected]",
        "isDefault": false
      }
    ],
    "availableTypes": [
      {
        "type": "card",
        "name": "Credit/Debit Card",
        "brands": ["visa", "mastercard", "amex", "discover"]
      },
      {
        "type": "digital_wallet",
        "name": "Digital Wallet",
        "providers": ["paypal", "apple_pay", "google_pay"]
      },
      {
        "type": "bank_transfer",
        "name": "Bank Transfer",
        "providers": ["ach", "wire"]
      }
    ]
  }
}

Add Payment Method

Add a new payment method to the user's account.

Endpoint: POST /payments/methods

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Request Body:

{
  "type": "card",
  "cardToken": "tok_visa_4242",
  "billingAddress": {
    "name": "John Doe",
    "street": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zipCode": "10001",
    "country": "US"
  },
  "setAsDefault": true
}

Response: 201 Created

{
  "success": true,
  "message": "Payment method added",
  "data": {
    "id": "pm_card_visa_2",
    "type": "card",
    "brand": "visa",
    "last4": "4242",
    "expiryMonth": 12,
    "expiryYear": 2025,
    "isDefault": true,
    "billingAddress": {
      "name": "John Doe",
      "street": "123 Main St",
      "city": "New York",
      "state": "NY",
      "zipCode": "10001",
      "country": "US"
    },
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}

Error Response: 400 Bad Request

{
  "success": false,
  "error": {
    "code": "INVALID_PAYMENT_METHOD",
    "message": "Invalid card token or card details"
  }
}

Delete Payment Method

Remove a payment method from the user's account.

Endpoint: DELETE /payments/methods/:id

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Path Parameters:

  • id: Payment method ID

Response: 200 OK

{
  "success": true,
  "message": "Payment method removed"
}

Error Response: 404 Not Found

{
  "success": false,
  "error": {
    "code": "PAYMENT_METHOD_NOT_FOUND",
    "message": "Payment method not found"
  }
}

Refund Payment

Initiate a refund for a completed payment.

Endpoint: POST /payments/:id/refund

Headers:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Path Parameters:

  • id: Payment ID

Request Body:

{
  "amount": 185.97,
  "reason": "customer_request",
  "notes": "Customer requested refund due to wrong item"
}

Response: 200 OK

{
  "success": true,
  "message": "Refund initiated",
  "data": {
    "refundId": "ref_abc123",
    "paymentId": "pay_xyz789",
    "orderId": "order_abc123",
    "status": "pending",
    "amount": 185.97,
    "currency": "USD",
    "reason": "customer_request",
    "estimatedArrival": "2024-01-08T00:00:00.000Z",
    "createdAt": "2024-01-01T00:00:00.000Z"
  }
}

Error Response: 400 Bad Request

{
  "success": false,
  "error": {
    "code": "REFUND_FAILED",
    "message": "Payment cannot be refunded (already refunded or too old)"
  }
}

Validation Rules:

  • amount: Optional, defaults to full payment amount, cannot exceed original amount
  • reason: Required, must be one of: customer_request, fraudulent, duplicate, wrong_item
  • Payment must be in succeeded status
  • Refunds must be initiated within 90 days of payment

Payment Webhooks

Receive payment status updates from payment providers. This endpoint is called by the payment provider, not by clients.

Endpoint: POST /payments/webhooks

Headers:

X-Webhook-Signature: sha256=abc123xyz789...
Content-Type: application/json

Request Body:

{
  "event": "payment.succeeded",
  "paymentId": "pay_xyz789",
  "orderId": "order_abc123",
  "transactionId": "txn_abc123xyz789",
  "amount": 185.97,
  "currency": "USD",
  "timestamp": "2024-01-01T00:05:00.000Z"
}

Response: 200 OK

{
  "success": true,
  "message": "Webhook processed"
}

Webhook Events:

  • payment.initiated: Payment session created
  • payment.succeeded: Payment completed successfully
  • payment.failed: Payment failed
  • payment.canceled: Payment canceled by user
  • refund.created: Refund initiated
  • refund.succeeded: Refund completed
  • refund.failed: Refund failed

Security:

  • All webhooks are signed with HMAC-SHA256
  • Verify the X-Webhook-Signature header before processing
  • Webhooks have a 5-minute tolerance for timestamp validation

Payment Status

StatusDescription
pendingPayment initiated, awaiting completion
processingPayment being processed by provider
succeededPayment completed successfully
failedPayment failed
canceledPayment canceled by user
refundedPayment fully refunded
partially_refundedPayment partially refunded

Error Codes

CodeDescription
UNAUTHORIZEDAuthentication required or token invalid
PAYMENT_NOT_FOUNDPayment not found
INVALID_ORDEROrder not found or already paid
INVALID_PAYMENT_METHODPayment method invalid or expired
PAYMENT_FAILEDPayment declined by provider
INSUFFICIENT_FUNDSInsufficient funds in account
REFUND_FAILEDRefund cannot be processed
WEBHOOK_VERIFICATION_FAILEDWebhook signature verification failed

Best Practices

  1. Always verify webhook signatures to prevent fraud
  2. Handle idempotency - use the same payment ID for retries
  3. Store payment receipts for customer records
  4. Implement payment retry logic with exponential backoff
  5. Use PCI-compliant payment providers - never store card details directly
  6. Monitor failed payments and provide clear error messages
  7. Handle 3D Secure (3DS) for card payments when required
  8. Set appropriate timeout values for payment confirmations (typically 30 seconds)

Security

  • All payment data is encrypted in transit using TLS 1.3
  • Card details are tokenized and never stored on servers
  • PCI DSS Level 1 compliant payment processing
  • 3D Secure 2.0 (3DS2) supported for card payments
  • Fraud detection and prevention built-in
  • Regular security audits and penetration testing

Rate Limits

  • Payment initiation: 20 requests per minute per user
  • Payment confirmation: 10 requests per minute per user
  • Payment method management: 30 requests per minute per user
  • Webhooks: No rate limit (verified by signature)

Exceeding rate limits will result in a 429 Too Many Requests response.

On this page