Core Concepts

Payment Intents

Understanding payment intents and their role in the payment lifecycle

A payment intent is a high-level abstraction that represents the entire payment process. It serves as a container for all the necessary information required to initiate and manage a payment transaction.

What is a Payment Intent?

Think of a payment intent as a "payment session" or "payment request" that captures:

  • Amount and Currency: How much to charge and in what currency
  • Customer Information: Who is making the payment (purchaser_id)
  • Transaction Reference: Your internal reference ID (reference_id)
  • Payment Preferences: Whether to save credentials, allow MIT, etc.
  • Current Status: Where the payment is in its lifecycle

When you create a payment intent, NjiaPay generates a secure checkout URL that you redirect your customer to. This URL remains valid until the payment is completed, canceled, or expired.

Intent vs Attempt

It's important to understand the relationship between intents and attempts:

  • Payment Intent: The overall payment request (e.g., "Customer wants to pay $100")
  • Payment Attempt: A specific try at processing that payment with a particular payment method (e.g., "Customer tried to pay with Visa card ending in 1234")

Key differences:

  • One intent can have multiple sequential attempts
  • If an attempt fails, the intent can be retried with a different payment method
  • The intent's status reflects the outcome of its most recent attempt

See Payment Attempts for more details on this relationship.

When to Create a Payment Intent

Create a payment intent whenever you want to collect a payment from a customer:

One-Time Payments

{
  "amount": 50000,
  "currency": "ZAR",
  "reference_id": "order_12345",
  "purchaser_id": "customer_abc",
  "return_url": "https://yoursite.com/callback",
  "allow_remember_credentials": false
}

First Payment with Credential Storage (for future auto-payments)

{
  "amount": 50000,
  "currency": "ZAR",
  "reference_id": "subscription_init",
  "purchaser_id": "customer_abc",
  "return_url": "https://yoursite.com/callback",
  "allow_remember_credentials": true,
  "request_unscheduled_mit": true
}

Payment with Splits

{
  "amount": 50000,
  "currency": "ZAR",
  "reference_id": "marketplace_order_789",
  "purchaser_id": "buyer_123",
  "return_url": "https://yoursite.com/callback",
  "allow_remember_credentials": false,
  "split": {
    "split_type": "AMOUNT",
    "splits": [
      {
        "beneficiary_id": "550e8400-e29b-41d4-a716-446655440000",
        "amount": 40000,
        "description": "Seller payment"
      },
      {
        "beneficiary_id": "main_merchant_id",
        "amount": 10000,
        "description": "Platform fee"
      }
    ]
  }
}

Intent Properties

Core Properties

PropertyTypeDescription
idUUIDUnique identifier for the intent
statusstringCurrent status (selection, pending, success, failed, canceled, chargeback)
amountintegerAmount in minor units (cents)
currencystringISO 4217 currency code
reference_idstringYour unique transaction reference
purchaser_idstringYour unique customer identifier
createddatetimeWhen the intent was created

Configuration Properties

PropertyTypeDescription
is_interactivebooleanWhether customer interaction is required
allow_remember_credentialsbooleanWhether credentials can be saved
request_unscheduled_mitbooleanRequest permission for auto-payments
require_unscheduled_mitbooleanRequire MIT capability
capture_modestringimmediate or prefer_delay
payment_method_filterobjectFilter available payment methods

Runtime Properties

PropertyTypeDescription
attempt_countintegerNumber of attempts made
last_methodstringLast payment method used
last_brandstringLast payment brand used
return_urlstringWhere to redirect customer after payment

Interactive vs Non-Interactive Intents

Interactive Intents (Default)

{
  "is_interactive": true,
  ...
}
  • Customer selects payment method via hosted checkout
  • Requires redirect_url to send customer to checkout page
  • Used for: First-time payments, customer-initiated payments

Non-Interactive Intents

{
  "is_interactive": false,
  ...
}
  • No customer interaction required
  • Used for auto-payments/MIT with stored credentials
  • Created via /api/intents/auto-attempt endpoint
  • See Auto Payments Guide

Intent Lifecycle

A payment intent progresses through various states based on payment attempts:

mermaid
stateDiagram-v2
    [*] --> Selection: Create Intent
    Selection --> Pending: Customer pays
    Pending --> Success: Payment Succeeds
    Pending --> Selection: Payment Fails (alternatives exist)
    Pending --> Failed: Payment Fails (no alternatives)
    Selection --> Canceled: User/Merchant Cancels
    Success --> Chargeback: Chargeback Filed
    Failed --> [*]
    Canceled --> [*]
    Chargeback --> [*]

See Status Lifecycle for detailed status explanations.

Best Practices

✅ DO

  • Use descriptive reference_id values for easy tracking
  • Set allow_remember_credentials: true only when needed
  • Handle all possible intent statuses in your webhook handler
  • Store the intent_id in your database for reconciliation
  • Use purchaser_info to pre-fill customer details

❌ DON'T

  • Create multiple intents for the same transaction
  • Rely solely on return_url for payment confirmation
  • Reuse reference_id values across different transactions
  • Expose the redirect_url or intent token to unauthorized users
  • Poll the API excessively, use webhooks instead

Security Considerations

Intent Tokens

When you create an intent, you receive a token (intent authentication token):

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
  "redirect_url": "https://app.infinic.com/checkout?intent=...&token=..."
}

This token (iauth parameter):

  • Allows customers to view their own payment intent
  • Cannot be used to access other intents
  • Is included automatically in the redirect_url
  • Should be treated as sensitive (but less sensitive than API keys)

PCI Compliance

By using payment intents with hosted checkout:

  • You never handle raw card data
  • NjiaPay manages PCI compliance
  • Sensitive data is encrypted at rest
  • Payment methods are tokenized

Payment Attempts

Learn about the intent-attempt relationship

Status Lifecycle

Understand status transitions

Create Intent API

API reference for creating intents

Hosted Checkout

Integration guide for checkout flow