Skip to main content

Initialize Transaction

Overview

The Initialise Transaction endpoint is the core operation for creating payment transactions. It accepts payment details, customer information, and optional settlement configurations to generate a transaction reference that can be used to process payments through various channels.

Endpoint Details

Endpoint: POST /api/v1/transactions/in/initialize

Purpose: Creates a new transaction for a selected payment item with specified amount and customer details

AuthorisationAuthentication: Requires Bearer token (merchant_secret_key) in Authorization header

Code Snippets

const url = "https://ags.payislands.com/api/v1/transactions/in/initialize";

const payload = {
callback_url: "https://example.com/webhooks/payislands",
payment_item_id: "3",
transaction_reference: "your_reference",
channel: "card",
amount: "1000",
customer_info: {
email: "test@gmail.com",
phone_number: "08011112222",
first_name: "John",
last_name: "Doe",
},
};

const res = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.MERCHANT_SECRET_KEY}`,
},
body: JSON.stringify(payload),
});

const json = await res.json();
console.log(json);

Request Body Structure

Required Fields

{
"callback_url": "string",
"payment_item_id": "string",
"transaction_reference":"your_reference",
"channel": "string",
"amount": "string",
"customer_info": {
"email": "string",
"phone_number": "string",
"first_name": "string",
"last_name": "string"
}
}

Optional Fields

{
"subaccounts": [
{
"account_code": "string",
"amount": integer
}
]
}

Field Descriptions

Request Fields

FieldTypeRequiredDescriptionExample
callback_urlstring (URL)YesPublic HTTPS endpoint to receive transaction updates. Must accept POST requests.https://example.com/webhooks/payislands
payment_item_idstring (numeric)YesPayment item ID (must exist and be active)."3"
transaction_referencestringYesYour internal reference for reconciliation (returned back as client_reference)."your_reference"
channelstringYesPayment channel to use: bank, card, bank-transfer."card"
amountstringYesAmount in smallest unit (kobo). Must match the payment item amount for fixed items. For variable items, set the payment item amount to 0 when creating it."1000"
customer_infoobjectYesCustomer details (see table below).{...}
subaccountsarrayNoOptional split override (see table below).[{...}]

customer_info Fields

FieldTypeRequiredDescriptionExample
customer_info.emailstringYesCustomer email address.test@gmail.com
customer_info.phone_numberstringYesCustomer phone number.08011112222
customer_info.first_namestringYesCustomer first name.John
customer_info.last_namestringYesCustomer last name.Doe

subaccounts[] Fields (Optional)

FieldTypeRequiredDescription
subaccounts[].account_codestringYes (if provided)Settlement account code.
subaccounts[].amountintegerYes (if provided)Amount to settle to this account. The sum of all subaccounts[].amount should equal the transaction amount.

Response Structure

Success Response (200 OK)

{
"status": true,
"message": "transaction generated successfully",
"data": {
"payment_status": "pending",
"authorization_url": "https://checkout.payislands.com/?reference=PISL2510010000000093",
"amount": "100.00",
"amount_to_be_paid": 101.7,
"transaction_fee": "1.70",
"reference": "PISL2510010000000093",
"client_reference": "your_reference"
},
"statusCode": 200
}

Response Fields

FieldTypeDescription
data.payment_statusstringCurrent status (usually pending immediately after initialization).
data.authorization_urlstring | nullCheckout URL to redirect the customer (typically present for card).
data.amountstringBase amount for the transaction.
data.amount_to_be_paidnumber | stringTotal amount expected (may include fees).
data.transaction_feestringProcessing fee (if applicable).
data.referencestringPayislands transaction reference. Store this for verification, webhooks, and support.
data.client_referencestringYour transaction_reference echoed back.

Failure Response (400 Bad Request)

{
"status": false,
"message": "Payment amount does not match",
"data": null,
"statusCode": 400
}

Common Error Scenarios

ScenarioTypical statusError / messageCauseFix
Amount mismatch400"Payment amount does not match"Submitted amount doesn’t match the payment item’s configured amount (for fixed items).Fetch the payment item details and submit the exact amount. For variable items, set the payment item amount to 0 when creating it.
Invalid payment item400Payment item not foundpayment_item_id doesn’t exist or is inactive.Call “Get Payment Items” and use a valid active ID.
Authentication failure403"Forbidden resource"Missing/invalid Authorization: Bearer <merchant_secret_key>.Confirm you are using the correct key (Test vs Live) and sending the header.
Invalid customer info400Validation errorMissing or malformed customer_info fields.Ensure all required fields exist and formats are valid (email, phone, name).
Subaccounts issues400Validation errorInvalid subaccounts[].account_code or the split amounts don’t add up.Verify each account_code and ensure the sum of subaccounts[].amount equals the transaction amount.

Implementation Flow

1. Pre-Transaction Steps

1. Fetch payment item details (GET /payment-item/{id})
2. Validate the amount matches the payment item configuration
3. Collect customer information
4. Prepare callback URL endpoint

2. Transaction Initialisation

1. Construct the request body with all required fields
2. Send POST request with Bearer token
3. Handle response (success or error)
4. Store transaction reference

3. Post-Initialisation

1. If authorization_url is provided:
- Redirect the customer to the payment page
- Wait for webhook callback
2. If no authorization_url:
- Provide payment instructions (for bank transfers)
- Monitor transaction status via webhook or polling

Best Practices

Amount Handling

  • Always retrieve and verify the payment item amount before initialisation
  • For variable-amount items, implement amount validation on your end
  • Store amounts as strings to avoid floating-point precision issues
  • Never hardcode amounts - always fetch from the payment items endpoint

Customer Data

  • Validate email format before submission
  • Normalise phone numbers (remove spaces, special characters)
  • Implement input validation for names (no special characters)
  • Consider data privacy regulations when storing customer information

Reference Management

  • Store transaction references in your database immediately
  • Use references as primary keys for transaction tracking
  • Include references in all customer communications
  • Implement reference-based transaction lookup functionality

Webhook Configuration

  • Use HTTPS endpoints for callback_url
  • Implement webhook signature verification (if available)
  • Handle duplicate webhook deliveries (idempotency)
  • Set up retry logic for failed webhook processing
  • Log all webhook payloads for debugging

Error Handling

  • Implement retry logic with exponential backoff for network errors
  • Log full error responses for debugging
  • Have fallback mechanisms for transaction verification

Security Considerations

  • Never expose merchant_secret_key in client-side code
  • Use HTTPS for all API communications

Subaccount

  • Only use subaccounts when custom splits are required
  • Verify account codes before use
  • Ensure split amounts sum to the transaction amount exactly

Channel Selection

  • Verify channel availability for specific payment items
  • Provide appropriate user experience per channel:
    • Card: Immediate redirect to authorization_url
    • Bank Transfer: Display account details and expiry time
    • Bank
  • Handle channel-specific error messages appropriately