Education Purchase

LIVE
Endpoint

Send a POST request with the purchase details in the request body.

Production URL
https://pairgate.com/api/v1/education/purchase
Method POST
Test Endpoint
https://pairgate.com/api/v1/test/education/purchase
Authentication

This request requires a valid Bearer token.

Header Value Description
Authorization
Bearer {token}
Your unique API authorization token
Content-Type
application/json
Required for POST requests
Body Parameters

All parameters are required. Send them as JSON in the request body.

Parameter Type Required Description
provider_id string Yes Provider slug (e.g. waec, neco, nabt)
quantity integer Yes Number of pins to purchase
reference string Yes Your unique reference for this transaction (8–100 characters)
Code Examples

Choose your preferred language below. Replace the parameters and YOUR_API_KEY with your actual values.

PHP (Laravel)
// Purchase Exam Pins
$response = Http::withHeaders([
    'Authorization' => 'Bearer YOUR_API_KEY',
    'Content-Type' => 'application/json',
])->post('https://pairgate.com/api/v1/education/purchase', [
    'provider_id' => 'waec',
    'quantity' => 2,
    'reference' => 'my-education-order-001',
]);

$result = $response->json();

dd($result);
cURL
curl -X POST "https://pairgate.com/api/v1/education/purchase" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "provider_id": "waec",
    "quantity": 2,
    "reference": "my-education-order-001"
  }'
Node.js
const axios = require('axios');

const purchaseExamPins = async () => {
    try {
        const response = await axios.post(
            'https://pairgate.com/api/v1/education/purchase',
            {
                provider_id: 'waec',
                quantity: 2,
                reference: 'my-education-order-001'
            },
            {
                headers: {
                    'Authorization': 'Bearer YOUR_API_KEY',
                    'Content-Type': 'application/json'
                }
            }
        );
        
        console.log(response.data);
    } catch (error) {
        console.error(error.response?.data || error.message);
    }
};

purchaseExamPins();
Python
import requests
import json

url = "https://pairgate.com/api/v1/education/purchase"

headers = {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
}

payload = {
    "provider_id": "waec",
    "quantity": 2,
    "reference": "my-education-order-001"
}

try:
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()
    data = response.json()
    print(json.dumps(data, indent=2))
except requests.exceptions.RequestException as e:
    print(f"Error: {e}")
Java
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;

HttpClient client = HttpClient.newHttpClient();

String jsonBody = "{"
    + "\"provider_id\": \"waec\","
    + "\"quantity\": 2,"
    + "\"reference\": \"my-education-order-001\""
    + "}";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://pairgate.com/api/v1/education/purchase"))
    .header("Authorization", "Bearer YOUR_API_KEY")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(jsonBody))
    .build();

try {
    HttpResponse response = client.send(request, 
        HttpResponse.BodyHandlers.ofString());
    
    System.out.println(response.body());
} catch (Exception e) {
    System.err.println("Error: " + e.getMessage());
}
Example Request Body
{
  "provider_id": "waec",
  "quantity": 2,
  "reference": "my-education-order-001"
}
Response Format
Success Response (200)

Purchase accepted, pins being generated:

{
  "code": 200,
  "status": "success",
  "data": {
    "status": true,
    "message": "Successfully purchased 2 exam pin(s). Processing will be completed shortly.",
    "reference": "my-education-order-001",
    "total_amount": 2000.00,
    "unit_price": 1000.00,
    "quantity": 2,
    "exam_type": "WAEC",
    "details": [
      {
        "reference": "TRXEXAM20260615104818CQ3",
        "pin": null
      },
      {
        "reference": "TRXEXAM20260615104818CQ4",
        "pin": null
      }
    ]
  }
}
Test Response (200)
{
  "code": 200,
  "status": "success",
  "data": {
    "test_mode": true,
    "message": "This is a test — no balance deducted.",
    "request": {
      "provider_id": "waec",
      "quantity": 2,
      "reference": "my-education-order-001"
    },
    "balance": 20000.00
  }
}
Success Response Fields
Field Type Description
status boolean true if successful
message string Status description
reference string Your original reference
total_amount float Total amount charged
unit_price float Price per pin
quantity integer Number of pins purchased
exam_type string Exam body name
details array Individual transaction references for each pin
Webhook — Pin Delivered

When each pin is generated, a webhook is sent to your configured URL. One webhook per pin. Ensure your webhook endpoint is set up to receive these POST notifications.

Webhook Payload
{
  "event": "waec.purchase",
  "reference_code": "TRXEXAM20260615104818CQ3",
  "status": "successful",
  "message": "Waec purchase completed.",
  "item": "Waec Exam Checker Pin",
  "amount": 1000.00,
  "pin": "WAEC-12345-67890-ABCDE",
  "completed_at": "2026-06-15T10:05:00+01:00"
}
Webhook Fields
Field Type Description
event string Purchase event type
reference_code string Matches one of the references from the details array
status string successful when the pin is ready
message string Status description
item string Exam body name
amount float Amount charged per pin
pin string The exam checker pin. For WAEC, format: PIN_NUMBER<=>SCRATCH_CARD_SERIAL (e.g. 12114234543543<=>WRN12345678). For NECO/NABTEB: just the pin number.
completed_at string Timestamp when the pin was generated
Pin Format Note: For WAEC, the pin is delivered as 12114234543543<=>WRN12345678 where the format is PIN_NUMBER<=>SCRATCH_CARD_SERIAL. For NECO and NABTEB, the pin is delivered as just the pin number with no <=> separator.
Error Responses

The following errors may occur when calling this endpoint.

Status Code Description
422 Invalid provider Provider not found or inactive
422 Unknown exam type Exam type not recognised
422 Insufficient balance Wallet balance is too low
422 Duplicate reference This reference has already been used
401 Missing API key No Bearer token provided
401 Invalid API key Token does not match any active key
403 Suspended API key or account has been suspended
429 Rate limited Too many requests