Complete guide for integrating the Nexzoneo Payment API
The Nexzoneo Pay API allows you to integrate secure payment processing into your applications. This guide provides comprehensive documentation on how to use the API effectively, including all available parameters, status codes, and implementation patterns.
Base URL:https://nexzoneo.com/api/merchant/
1. Active merchant account with Nexzoneo Pay
2. Site configured in the merchant dashboard
3. API credentials (Site Key and Security Token)
4. Server-side implementation (required for security)
1. Set up your server-side endpoint
2. Configure authentication headers
3. Create payment sessions using the API
4. Handle webhook notifications
5. Test with test mode enabled
All API requests must include authentication headers. Never expose credentials in client-side code.
``http
X-Site-Key: your_site_key_here
Authorization: your_security_token_here
Content-Type: application/json
`
Security Requirements
- All API calls must be made from your server (PHP, Node.js, Python, etc.)
- Never include credentials in client-side JavaScript, mobile apps, or HTML
- Store credentials securely using environment variables
- Your client should call your server, which then calls our API
API Endpoints
Payment Session Management
#### 1. Create Payment Session
Endpoint: POST /create_payment_session
Creates a new payment session for processing customer payments.
#### Required Parameters
Parameter Type Description
---------------- ------ -------------------------------------------------------------------
order_id string Unique identifier for your order (must be unique per merchant site)
total number Total amount to charge (positive number, supports decimals)
currency string Currency code (e.g., "USD", "EUR", "GBP")
customer_email string Customer's email address (used for receipts and notifications)
#### Optional Parameters
Parameter Type Description
-------------- ------ --------------------------------------------------------------
items array Array of order items (see Items Structure)
return_url string Override site's default success redirect URL
cancel_url string Override site's default cancellation redirect URL
callback_url string Override site's default webhook URL
#### Items Structure
Each item in the
items array should contain:
`json
{
"name": "Product Name",
"quantity": 1,
"unit_price": 29.99
}
`
#### Example Request
`json
{
"order_id": "ORDER-2024-001",
"total": 99.99,
"currency": "USD",
"customer_email": "customer@example.com",
"items": [
{
"name": "Premium Subscription",
"quantity": 1,
"unit_price": 99.99
}
],
"return_url": "https://yourdomain.com/success",
"cancel_url": "https://yourdomain.com/cancel",
"callback_url": "https://yourdomain.com/webhook"
}
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"session_id": 12345,
"session_token": "sess_abc123def456...",
"payment_url": "https://payment.nexzoneo.com/session/sess_abc123def456...",
"reused": false
},
"request_id": "req_abc123",
"duration_ms": 45.2
}
`
Next Steps: Redirect the customer to the payment_url to complete payment.
#### 2. Get Session Details
Endpoint: GET /get_session?token={session_token}
Retrieves current details about a payment session.
#### Query Parameters
Parameter Type Description
--------- ------ --------------------------------------------
token string Payment session token from creation response
#### Example Request
`http
GET /get_session?token=sess_abc123def456...
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"session": {
"id": 12345,
"session_token": "sess_abc123def456...",
"external_order_id": "ORDER-2024-001",
"customer_email": "customer@example.com",
"amount": "99.99",
"currency": "USD",
"status": 2,
"current_status": 2,
"created_at": "2024-01-15 10:30:00",
"completed_at": "2024-01-15 10:35:00",
"expires_at": "2024-01-15 11:30:00",
"payment_method": "card"
}
},
"request_id": "req_def789",
"duration_ms": 12.8
}
`
Refund Management
#### 3. Create Refund
Endpoint: POST /create_refund
Creates a refund for a completed payment. Only payments with status
COMPLETED or PARTIALLY_REFUNDED can be refunded.
#### Required Parameters
Parameter Type Description
------------ ------ -----------------------------------------------------------------
session_id number Payment session ID to refund
amount number Refund amount (must be positive, up to remaining balance)
reason string Refund reason: duplicate, fraudulent, requested_by_customer
#### Optional Parameters
Parameter Type Description
--------- ------ -------------------------------
comment string Optional comment for the refund
#### Example Request
`json
{
"session_id": 12345,
"amount": 29.99,
"reason": "requested_by_customer",
"comment": "Customer requested refund due to order cancellation"
}
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"message": "Refund processed successfully",
"refund_id": 456,
"transaction_id": "txn_1234567890abcdef"
},
"request_id": "req_abc456",
"duration_ms": 1250.3
}
`
#### 4. Get Refund Status
Endpoint: GET /get_refund_status?refund_id={refund_id}
Retrieves the current status of a specific refund.
#### Query Parameters
Parameter Type Description
----------- ------ -------------------------------------
refund_id number Refund ID from create_refund response
#### Example Request
`http
GET /get_refund_status?refund_id=456
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"refund": {
"id": 456,
"session_id": 12345,
"payment_intent_id": "pi_1234567890abcdef",
"transaction_id": "txn_1234567890abcdef",
"amount": "29.99",
"currency": "USD",
"reason": "requested_by_customer",
"status": "succeeded",
"admin_comment": "Customer requested refund due to order cancellation",
"created_at": "2024-01-15 11:00:00",
"updated_at": "2024-01-15 11:00:15"
}
},
"request_id": "req_def456",
"duration_ms": 23.1
}
`
#### 5. List Refunds
Endpoint: GET /list_refunds?session_id={session_id}
Lists all refunds for a specific payment session.
#### Query Parameters
Parameter Type Description
------------ ------ ---------------------------------------
session_id number Payment session ID to query refunds for
#### Example Request
`http
GET /list_refunds?session_id=12345
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"refunds": [
{
"id": 456,
"session_id": 12345,
"payment_intent_id": "pi_1234567890abcdef",
"transaction_id": "txn_1234567890abcdef",
"amount": "29.99",
"currency": "USD",
"reason": "requested_by_customer",
"status": "succeeded",
"admin_comment": "Customer requested refund",
"created_at": "2024-01-15 11:00:00",
"updated_at": "2024-01-15 11:00:15"
}
],
"total_refunded": "29.99"
},
"request_id": "req_ghi789",
"duration_ms": 18.5
}
`
Chargeback Management
#### 6. Create Chargeback
Endpoint: POST /create_chargeback
Creates a chargeback record for dispute management and evidence submission.
#### Required Parameters
Parameter Type Description
---------------- ------ -------------------------------------------
session_id number Payment session ID to create chargeback for
amount number Chargeback amount
reason string Chargeback reason code
dispute_reason string Detailed reason for the dispute
#### Optional Parameters
Parameter Type Description
----------------- ------ ---------------------------------------------
evidence_due_by string Due date for evidence submission (YYYY-MM-DD)
admin_comment string Internal comment for chargeback management
#### Example Request
`json
{
"session_id": 12345,
"amount": 29.99,
"reason": "fraudulent",
"dispute_reason": "Customer claims unauthorized transaction",
"evidence_due_by": "2024-02-15",
"admin_comment": "Investigating with customer service logs"
}
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"message": "Chargeback created successfully",
"chargeback_id": 789,
"status": "open"
},
"request_id": "req_chb123",
"duration_ms": 156.7
}
`
#### 7. Submit Chargeback Evidence
Endpoint: POST /submit_chargeback_evidence
Submits evidence to dispute a chargeback.
#### Required Parameters
Parameter Type Description
--------------- ------ ------------------------------------
chargeback_id number Chargeback ID to submit evidence for
evidence object Evidence documentation
#### Evidence Object Structure
Field Type Description
------------------------ ------ -----------------------------------
customer_communication string Customer emails, chat logs, etc.
shipping_documentation string Tracking numbers, delivery proof
service_documentation string Service usage logs, screenshots
billing_documentation string Invoices, receipts, billing records
#### Example Request
`json
{
"chargeback_id": 789,
"evidence": {
"customer_communication": "Email thread showing customer satisfaction with purchase",
"shipping_documentation": "Tracking #1234567890 - Delivered 2024-01-10",
"service_documentation": "Customer used service for 30 days with 50+ logins",
"billing_documentation": "Invoice #INV-001 sent and acknowledged by customer"
}
}
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"message": "Evidence submitted successfully",
"chargeback_id": 789,
"status": "evidence_submitted"
},
"request_id": "req_evd456",
"duration_ms": 234.1
}
`
#### 8. Get Chargeback History
Endpoint: GET /get_chargeback_history?session_id={session_id}
Retrieves all chargebacks for a specific payment session.
#### Query Parameters
Parameter Type Description
------------ ------ -------------------------------------------
session_id number Payment session ID to query chargebacks for
#### Example Request
`http
GET /get_chargeback_history?session_id=12345
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"chargebacks": [
{
"id": 789,
"session_id": 12345,
"payment_intent_id": "pi_1234567890abcdef",
"amount": "29.99",
"currency": "USD",
"reason": "fraudulent",
"dispute_reason": "Customer claims unauthorized transaction",
"status": "evidence_submitted",
"evidence_due_by": "2024-02-15",
"created_at": "2024-01-20 14:30:00",
"updated_at": "2024-01-22 10:15:00"
}
]
},
"request_id": "req_hist789",
"duration_ms": 45.3
}
`
#### 9. Accept Chargeback
Endpoint: POST /accept_chargeback
Accepts a chargeback without disputing it.
#### Required Parameters
Parameter Type Description
--------------- ------ -----------------------
chargeback_id number Chargeback ID to accept
#### Optional Parameters
Parameter Type Description
--------- ------ -----------------------------------
reason string Reason for accepting the chargeback
#### Example Request
`json
{
"chargeback_id": 789,
"reason": "Valid customer complaint - accepting chargeback"
}
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"message": "Chargeback accepted successfully",
"chargeback_id": 789,
"status": "accepted"
},
"request_id": "req_acc321",
"duration_ms": 123.4
}
`
Payment Link Management
Payment Links are merchant-issued invoices a customer can pay without you building a
checkout page - useful for phone/email orders, deposits, one-off services, or B2B
invoicing. This feature must be enabled for your merchant account first (contact
support or your Nexzoneo admin); calls from a merchant without it enabled get a 403.
Creating a link does not email it. Pass
send_email: true on create, or call
send-payment-link afterwards - this is deliberate, so integrating against this API
cannot accidentally email a real customer while you are still testing.
amount cannot be changed after creation (update-payment-link refuses it with 400).
To change the price - e.g. adding a late fee - cancel the link and create a new one
with
supersedes_link_id pointing at the cancelled one.
#### 10. Create Payment Link
Endpoint: POST /create-payment-link
#### Required Parameters
Parameter Type Description
---------------- ------ -----------------------------------------
description string What the customer is paying for (≤255 chars), shown on the pay page
amount number Positive, up to 99,999,999.99. Cannot be changed later.
customer_email string Where the invoice email is sent
#### Optional Parameters
Parameter Type Description
---------------------- ------- --------------------------------------------------------------------
currency string ISO 4217 code. Defaults to USD.
customer_name string Shown on the pay page and in the invoice email
reference string Your own order/invoice number, echoed back in list/get
due_at date Cosmetic only - reminders stop after this date, the link stays payable
expires_at date Also cosmetic - does not block payment. There is deliberately no hard-expiry; cancel the link instead.
supersedes_link_id integer id of a cancelled link you own that this one replaces (re-issue with a late fee)
send_email boolean Email the invoice immediately. Default false.
#### Example Request
`json
{
"description": "Consultation fee — initial appointment",
"amount": 240.00,
"currency": "USD",
"customer_email": "customer@example.com",
"customer_name": "Jane Patient",
"reference": "INV-1042",
"due_at": "2026-10-04"
}
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"payment_link": {
"id": 118,
"token": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"url": "https://payment.nexzoneo.com/pay/a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"reference": "INV-1042",
"description": "Consultation fee — initial appointment",
"amount": 240.00,
"currency": "USD",
"customer_name": "Jane Patient",
"customer_email": "customer@example.com",
"status": "created",
"payable": true,
"cancellable": true,
"deletable": true,
"test": false,
"due_at": "2026-10-04 00:00:00",
"expires_at": null,
"reminder_count": 0,
"sent_at": null,
"first_viewed_at": null,
"paid_at": null,
"cancelled_at": null,
"cancel_reason": null,
"supersedes_link_id": null,
"created_at": "2026-09-20 12:00:00"
}
},
"request_id": "req_pl001",
"duration_ms": 22.4
}
`
Error responses: 400 missing/invalid field, 403 payment links not enabled for this merchant.
#### 11. Send (or Resend) Invoice Email
Endpoint: POST /send-payment-link
Emails the invoice to
customer_email. Safe to call again on an already-sent
link - it is treated as a resend (e.g. after correcting a typo'd address) and
does not reset
sent_at or the reminder schedule.
#### Required Parameters
Parameter Type Description
--------- ------- -------------------
id integer Payment link id
#### Example Request
`json
{ "id": 118 }
`
#### Success Response
Same shape as Create (the updated
payment_link, now with sent_at populated).
Error responses: 400 missing id, 404 unknown or not-yours, 409 link is
already paid or cancelled and can no longer be sent.
#### 12. List Payment Links
Endpoint: GET /list-payment-links?status=&site_id=&limit=&offset=
Scoped to your merchant account - never returns another merchant's links.
#### Query Parameters
Parameter Type Description
---------- ------- ------------------------------------------------------
status string Single status, or comma-separated list (e.g. created,viewed)
site_id integer Restrict to one of your sites
limit integer Default 50, max 200
offset integer Default 0
#### Example Request
`http
GET /list-payment-links?status=created,viewed&limit=20
`
#### Success Response
`json
{
"status": "success",
"data": {
"success": true,
"payment_links": [ { "id": 118, "status": "viewed", "...": "..." } ],
"total": 1,
"limit": 20,
"offset": 0
},
"request_id": "req_pl_list",
"duration_ms": 18.9
}
`
#### 13. Get Payment Link
Endpoint: GET /get-payment-link?id={id} or GET /get-payment-link?token={token}
Fetch by internal
id, or by the token that appears in the public pay URL.
#### Success Response
Same shape as Create.
404 if the id/token does not exist or belongs to another merchant.
#### 14. Update Payment Link
Endpoint: POST /update-payment-link
Correction, not re-pricing.
amount is deliberately not accepted here (400).
#### Required Parameters
Parameter Type Description
--------- ------- --------------
id integer Payment link id
#### Optional Parameters (any subset)
Parameter Type
------------------ ------
customer_email string
customer_name string
description string
reference string
due_at date
expires_at date
#### Example Request
`json
{ "id": 118, "customer_email": "jane.patient@example.com" }
`
Error responses: 400 invalid field value or an attempt to change amount,
404 not found/not yours, 409 link is paid or cancelled and can no longer be edited.
#### 15. Cancel Payment Link
Endpoint: POST /cancel-payment-link
Stops the link from being payable - the public pay page returns
410 Gone
afterwards. This is how you kill an unpaid invoice before re-issuing it (see
supersedes_link_id on create). Allowed even after the customer has viewed it.
Idempotent - cancelling an already-cancelled link returns 200, not an error.
#### Parameters
Parameter Type Required Description
--------- ------- -------- --------------------------------
id integer Yes Payment link id
reason string No Stored on the link, shown to you
#### Example Request
`json
{ "id": 118, "reason": "Customer requested cancellation" }
`
Error responses: 404 not found/not yours, 409 already paid (issue a refund instead).
#### 16. Delete Payment Link
Endpoint: POST /delete-payment-link (or DELETE, same body)
Hard delete. Only allowed while the customer has never interacted with the
link (
status is created or sent - never viewed, paid, or cancelled).
Anything else must be cancelled instead.
#### Required Parameters
Parameter Type Description
--------- ------- ----------------
id integer Payment link id
#### Success Response
`json
{
"status": "success",
"data": { "success": true, "deleted": true, "id": 118 },
"request_id": "req_pl_del",
"duration_ms": 9.7
}
`
Error responses: 404 not found/not yours, 409 link has already been
viewed, paid, or cancelled - cancel it instead.
Payment Session Status Codes
Understanding status codes is crucial for handling payment states correctly.
Status Values
Code Name Description
---- ------------ --------------------------------------------------------
0 CREATED Session created, customer hasn't started payment
1 PROCESSING Customer is actively completing payment
2 COMPLETED Payment successful and confirmed
3 FAILED Payment failed (card declined, insufficient funds, etc.)
4 EXPIRED Session expired before completion
5 CANCELLED Payment cancelled by customer or merchant
Status vs Current Status
status: The base status stored in the database
current_status: The computed current status considering expiration
The
current_status field automatically shows 4 (EXPIRED) when a session passes its expiration time, even if the database status is still 0 or 1. This provides real-time status without requiring database updates for every expired session.
Status Transitions
Valid status transitions:
CREATED → PROCESSING → COMPLETED
CREATED → PROCESSING → FAILED
CREATED → CANCELLED
PROCESSING → CANCELLED
- Any non-terminal status →
EXPIRED (automatic)
Terminal statuses (no further changes):
COMPLETED, FAILED, EXPIRED, CANCELLED
Response Format
All API responses follow a consistent structure:
`json
{
"status": "success
error",
"data": {
// Response data here
},
"request_id": "req_unique_id",
"duration_ms": 45.2
}
`
Response Headers
Content-Type: application/json
X-Request-ID: req_unique_id
X-Request-Duration: 45.2ms
Parameters Reference
Currency Support
Supported currencies depend on your site configuration. Common currencies:
USD - US Dollar
EUR - Euro
GBP - British Pound
CAD - Canadian Dollar
AUD - Australian Dollar
Amount Formatting
- Use decimal numbers (e.g.,
29.99, not 2999)
- Precision: up to 2 decimal places
- Must be positive (greater than 0)
- Minimum amount varies by currency
URL Parameters
All URL parameters (
return_url, cancel_url, callback_url) must:
- Be valid, accessible URLs
- Use HTTPS in production
- Accept the appropriate HTTP methods (GET for redirects, POST for webhooks)
Webhooks
Webhooks provide real-time notifications about payment status changes.
Webhook Payload
When a payment status changes, a POST request is sent to your callback URL:
`json
{
"order_id": "ORDER-2024-001",
"total": "99.99",
"currency": "USD",
"payment_status": "completed",
"session_status": "completed",
"transaction_ref": "TXN-789",
"customer_email": "customer@example.com",
"timestamp": "1705320900",
"signature": "hmac_signature_here"
}
`
Webhook Verification
Always verify webhook authenticity:
`php
$data = $_POST;
$received_signature = $data['signature'];
unset($data['signature']);
ksort($data);
$expected_signature = hash_hmac('sha256', json_encode($data), $your_security_token);
if (hash_equals($expected_signature, $received_signature)) {
// Webhook is authentic - process the data
$order_id = $data['order_id'];
$payment_status = $data['payment_status'];
// Update your database
// Send confirmation emails
// etc.
} else {
// Invalid webhook - log and ignore
error_log('Invalid webhook signature');
}
?>
`
Payment Status Values in Webhooks
pending - Payment is being processed
completed - Payment was successful
failed - Payment failed
cancelled - Payment was cancelled
expired - Payment session expired
partially_refunded - Payment has been partially refunded
fully_refunded - Payment has been fully refunded
Refund Status Values
Refund status values returned in refund API responses:
pending - Refund is being processed
succeeded - Refund was successful
failed - Refund failed
canceled - Refund was canceled
Error Handling
Error Response Format
`json
{
"status": "error",
"data": {
"error": "Error description",
"fields": ["field1", "field2"] // For validation errors
},
"request_id": "req_error123",
"duration_ms": 5.2
}
`
Common HTTP Status Codes
Code Description Common Causes
----- --------------------- ---------------------------------------------
400 Bad Request Missing/invalid parameters, invalid amounts
401 Unauthorized Invalid or missing credentials
404 Not Found Invalid endpoint or session not found
405 Method Not Allowed Wrong HTTP method (e.g., GET instead of POST)
500 Internal Server Error Server-side issues
Error Handling Best Practices
1. Always check the HTTP status code
2. Parse error messages for user-friendly display
3. Log errors for debugging
4. Implement retry logic for temporary failures
5. Validate data before sending requests
Common Refund Errors
Error Message Description Solution
---------------------------------------------------- ------------------------------------------- ----------------------------------------------------------
Payment session not found or access denied Invalid session ID or not owned by merchant Verify session ID and ownership
Refund amount must be greater than zero Invalid refund amount Check amount is positive number
Invalid refund reason Reason not in allowed list Use: duplicate, fraudulent, or requested_by_customer
Refund not allowed: Payment is older than 120 days Payment processor refund deadline exceeded Cannot refund payments older than 120 days
Refund amount exceeds remaining balance Attempting to refund more than available Check remaining refundable amount first
Testing
Test Mode
Enable test mode in your merchant site settings for safe testing:
- No real payments are processed
- Session tokens are prefixed with
TEST_
- Use test card numbers for different scenarios
Test Card Numbers
Card Number Scenario
------------------ ------------------
4242424242424242 Successful payment
4000000000000002 Card declined
4000000000009995 Insufficient funds
4000000000000069 Expired card
4000000000000127 Incorrect CVC
Testing Checklist
#### Payment Testing
- [ ] Successful payment flow
- [ ] Failed payment handling
- [ ] Webhook reception and verification
- [ ] Session expiration
- [ ] Cancel payment flow
- [ ] Error scenarios
- [ ] Status polling
- [ ] Duplicate order ID handling
#### Refund Testing
- [ ] Full refund of completed payment
- [ ] Partial refund of completed payment
- [ ] Multiple partial refunds
- [ ] Refund status checking
- [ ] Refund list retrieval
- [ ] Invalid session ID handling
- [ ] Invalid refund amount handling
- [ ] Invalid refund reason handling
- [ ] Already fully refunded payment
- [ ] Refund of test payments
#### Payment Link Testing
- [ ] Create a link, confirm it is not emailed by default
- [ ] Create with
send_email: true, confirm the invoice arrives
- [ ] Send / resend an existing link, confirm
sent_at does not change on resend
- [ ] Public pay page renders and marks the link
viewed
- [ ] Attempt to change
amount via update (expect 400)
- [ ] Cancel a link, confirm the pay page returns
410 Gone
- [ ] Re-issue a cancelled link with
supersedes_link_id (e.g. adding a late fee)
- [ ] Attempt to delete a link that has been viewed (expect 409)
- [ ] Cross-merchant access to another merchant's link (expect 404, not 403)
- [ ] Merchant without the feature enabled (expect 403)
Best Practices
Security
1. Never expose API credentials in client-side code
2. Always validate webhook signatures before processing
3. Use HTTPS for all URLs in production
4. Implement proper access controls for your webhook endpoints
5. Log security events for monitoring
Performance
1. Cache site settings to reduce API calls
2. Implement request timeouts (recommended: 30 seconds)
3. Use appropriate retry strategies with exponential backoff
4. Monitor API response times and error rates
User Experience
1. Redirect users promptly to payment URLs
2. Handle all payment outcomes (success, failure, cancel)
3. Provide clear error messages to users
4. Implement loading states during API calls
5. Send confirmation emails after successful payments
Development
1. Use test mode during development
2. Validate input data before API calls
3. Implement proper error handling and logging
4. Test webhook endpoints thoroughly
5. Monitor for duplicate payments using order IDs
Integration Examples
PHP Example
`php
class Nexzoneoment {
private $siteKey;
private $securityToken;
private $baseUrl = 'https://nexzoneo.com/api/merchant/';
public function __construct($siteKey, $securityToken) {
$this->siteKey = $siteKey;
$this->securityToken = $securityToken;
}
public function createPaymentSession($orderData) {
$url = $this->baseUrl . 'create_payment_session';
$headers = [
'Content-Type: application/json',
'X-Site-Key: ' . $this->siteKey,
'Authorization: ' . $this->securityToken
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($orderData),
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
return json_decode($response, true);
} else {
throw new Exception('API Error: ' . $response);
}
}
public function getSession($token) {
$url = $this->baseUrl . 'get_session?token=' . urlencode($token);
$headers = [
'X-Site-Key: ' . $this->siteKey,
'Authorization: ' . $this->securityToken
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_TIMEOUT => 30
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
return json_decode($response, true);
} else {
throw new Exception('API Error: ' . $response);
}
}
public function verifyWebhook($postData, $signature) {
$data = $postData;
unset($data['signature']);
ksort($data);
$expectedSignature = hash_hmac('sha256', json_encode($data), $this->securityToken);
return hash_equals($expectedSignature, $signature);
}
}
// Usage Example
try {
$nexzoneo = new NexzoneoPayment(
$_ENV['NEXZONEO_SITE_KEY'],
$_ENV['NEXZONEO_SECURITY_TOKEN']
);
$orderData = [
'order_id' => 'ORDER-' . time(),
'total' => 29.99,
'currency' => 'USD',
'customer_email' => 'customer@example.com',
'items' => [
[
'name' => 'Premium Plan',
'quantity' => 1,
'unit_price' => 29.99
]
]
];
$result = $nexzoneo->createPaymentSession($orderData);
if ($result['status'] === 'success') {
header('Location: ' . $result['data']['payment_url']);
exit;
} else {
throw new Exception('Payment session creation failed');
}
} catch (Exception $e) {
error_log('Payment error: ' . $e->getMessage());
// Show user-friendly error message
}
?>
`
Node.js Example
`javascript
const express = require("express");
const fetch = require("node-fetch");
const crypto = require("crypto");
class Nexzoneoment {
constructor(siteKey, securityToken) {
this.siteKey = siteKey;
this.securityToken = securityToken;
this.baseUrl = "https://nexzoneo.com/api/merchant/";
}
async createPaymentSession(orderData) {
const response = await fetch(this.baseUrl + "create_payment_session", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Site-Key": this.siteKey,
Authorization: this.securityToken,
},
body: JSON.stringify(orderData),
timeout: 30000,
});
const result = await response.json();
if (!response.ok) {
throw new Error(
API Error: ${result.data?.error "Unknown error"});
}
return result;
}
async getSession(token) {
const response = await fetch(
this.baseUrl +
get_session?token=${encodeURIComponent(token)},
{
headers: {
"X-Site-Key": this.siteKey,
Authorization: this.securityToken,
},
timeout: 30000,
}
);
const result = await response.json();
if (!response.ok) {
throw new Error(
API Error: ${result.data?.error "Unknown error"});
}
return result;
}
verifyWebhook(postData, signature) {
const data = { ...postData };
delete data.signature;
const sortedKeys = Object.keys(data).sort();
const sortedData = {};
sortedKeys.forEach((key) => {
sortedData[key] = data[key];
});
const expectedSignature = crypto
.createHmac("sha256", this.securityToken)
.update(JSON.stringify(sortedData))
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expectedSignature, "hex")
);
}
}
// Express.js integration
const app = express();
app.use(express.json());
const nexzoneo = new NexzoneoPayment(
process.env.NEXZONEO_SITE_KEY,
process.env.NEXZONEO_SECURITY_TOKEN
);
app.post("/create-payment", async (req, res) => {
try {
const orderData = {
order_id:
ORDER-${Date.now()},
total: req.body.amount,
currency: req.body.currency
"USD",
customer_email: req.body.email,
items: req.body.items
[],
};
const result = await nexzoneo.createPaymentSession(orderData);
res.json(result.data);
} catch (error) {
console.error("Payment creation error:", error.message);
res.status(500).json({ error: "Payment creation failed" });
}
});
app.post("/webhook", async (req, res) => {
try {
const isValid = nexzoneo.verifyWebhook(req.body, req.body.signature);
if (!isValid) {
console.error("Invalid webhook signature");
return res.status(400).send("Invalid signature");
}
// Process the webhook
const { order_id, payment_status } = req.body;
console.log(Payment ${order_id} status: ${payment_status});
// Update your database here
// Send confirmation emails
res.status(200).send("OK");
} catch (error) {
console.error("Webhook processing error:", error.message);
res.status(500).send("Error processing webhook");
}
});
`
Python Example
`python
import requests
import hmac
import hashlib
import json
from typing import Dict, Any
class Nexzoneoment:
def __init__(self, site_key: str, security_token: str):
self.site_key = site_key
self.security_token = security_token
self.base_url = 'https://nexzoneo.com/api/merchant/'
def create_payment_session(self, order_data: Dict[str, Any]) -> Dict[str, Any]:
url = self.base_url + 'create_payment_session'
headers = {
'Content-Type': 'application/json',
'X-Site-Key': self.site_key,
'Authorization': self.security_token
}
response = requests.post(
url,
headers=headers,
json=order_data,
timeout=30
)
result = response.json()
if response.status_code != 200:
raise Exception(f'API Error: {result.get("data", {}).get("error", "Unknown error")}')
return result
def get_session(self, token: str) -> Dict[str, Any]:
url = f'{self.base_url}get_session?token={token}'
headers = {
'X-Site-Key': self.site_key,
'Authorization': self.security_token
}
response = requests.get(url, headers=headers, timeout=30)
result = response.json()
if response.status_code != 200:
raise Exception(f'API Error: {result.get("data", {}).get("error", "Unknown error")}')
return result
def verify_webhook(self, post_data: Dict[str, Any], signature: str) -> bool:
data = post_data.copy()
data.pop('signature', None)
# Sort the data
sorted_data = {k: data[k] for k in sorted(data.keys())}
expected_signature = hmac.new(
self.security_token.encode(),
json.dumps(sorted_data, separators=(',', ':')).encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected_signature, signature)
Usage example
import os
from datetime import datetime
nexzoneo = NexzoneoPayment(
os.getenv('NEXZONEO_SITE_KEY'),
os.getenv('NEXZONEO_SECURITY_TOKEN')
)
try:
order_data = {
'order_id': f'ORDER-{int(datetime.now().timestamp())}',
'total': 29.99,
'currency': 'USD',
'customer_email': 'customer@example.com',
'items': [
{
'name': 'Premium Plan',
'quantity': 1,
'unit_price': 29.99
}
]
}
result = nexzoneo.create_payment_session(order_data)
if result['status'] == 'success':
payment_url = result['data']['payment_url']
print(f'Redirect user to: {payment_url}')
else:
raise Exception('Payment session creation failed')
except Exception as e:
print(f'Error: {e}')
``
---
This guide covers all aspects of using the Nexzoneo Pay API effectively. For additional support or questions, please contact our developer support team.
Need help? Contact Support