Payment Webhook

HTTP Method: POST
Endpoint URL: https://your-server.com/webhooks/payment (configured in your ALPPAY settings)
Description: ALPPAY sends this webhook to notify your server about payment creation or status changes.
Security: Verify the X-HMAC header to ensure the request is from ALPPAY.

Webhook Configuration

To receive payment webhooks:

  1. Contact [email protected] with your webhook endpoint URL
  2. Ensure your endpoint accepts POST requests
  3. Implement HMAC signature verification for security
  4. Respond with HTTP 200 OK to acknowledge receipt

Request Headers

  • Content-Type: application/json
  • X-HMAC: signature_string — HMAC-SHA256 signature of the request body

Request Body (JSON)

{
  "id": "285d8dce-7663-4580-ba7f-8afb2f2d3292",
  "transactions": [
    {
      "paymentId": "285d8dce-7663-4580-ba7f-8afb2f2d3292",
      "txnId": "0xe7238caa68382485141be0443d6ba7efd0bd9f6bac5a624bd059acc53af1bf1d19",
      "receivedAmount": "20.00",
      "asset": {
        "short": "USDT",
        "name": "Tether",
        "logoUrl": "https://cryptologos.cc/logos/tether-usdt-logo.png",
        "network": "tron"
      },
      "destTag": null,
      "addressFrom": "TXkFpL3HmzE9KPpXGWNXdCbNcDYYn73U4C",
      "addressTo": "TPSMckmxoQBQWfUcasbUs2cRUdh2EMQu4n",
      "date": "2025-05-20T12:34:56Z"
    }
  ],
  "amount": "1000.00",
  "totalReceivedAmount": "20.00",
  "asset": {
    "short": "USDT",
    "name": "Tether",
    "logoUrl": "https://cryptologos.cc/logos/tether-usdt-logo.png",
    "network": "tron"
  },
  "addressTo": "TPSMckmxoQBQWfUcasbUs2cRUdh2EMQu4n",
  "confirmsNeeded": 10,
  "timeout": 9000,
  "checkoutUrl": "https://your-shop.com/orders/40113049",
  "status": "OPEN",
  "customer": {
    "id": 12312312,
    "name": "John",
    "email": "[email protected]"
  },
  "merchant": {
    "id": "285d8dce-7663-4580-ba7f-8afb2f2d3292",
    "name": "Your Company",
    "siteUrl": "https://your-shop.com",
    "logoUrl": "https://your-shop.com/logo.svg",
    "email": "[email protected]"
  },
  "invoice": "INV-001",
  "paymentRedirectUrl": "https://a-pay-system.com/en/invoice?id=285d8dce-7663-4580-ba7f-8afb2f2d3292",
  "createdAt": "2025-05-20T12:34:56Z",
  "updatedAt": "2025-05-20T12:34:56Z"
}

Field Descriptions

  • id — Unique payment identifier
  • transactions — Array of blockchain transactions:
    • paymentId — Reference to parent payment ID
    • txnId — Blockchain transaction hash
    • receivedAmount — Amount received in this transaction
    • asset — Cryptocurrency details
    • destTag — Destination tag if applicable
    • addressFrom — Sender's wallet address
    • addressTo — Receiving wallet address
    • date — Transaction timestamp
  • amount — Requested payment amount
  • totalReceivedAmount — Sum of all received transactions
  • asset — Primary payment cryptocurrency details
  • addressTo — Payment receiving address
  • confirmsNeeded — Required blockchain confirmations
  • timeout — Payment expiration time in seconds
  • checkoutUrl — Merchant's return URL
  • status — Current payment status
  • customer — Customer information
  • merchant — Merchant account details
  • invoice — Merchant's invoice reference
  • paymentRedirectUrl — ALPPAY payment page URL
  • createdAt — Payment creation timestamp
  • updatedAt — Last update timestamp

Webhook Events and Status Changes

ALPPAY sends webhooks for the following payment events:

1. Payment Created (Status: OPEN)

Sent when a new payment is created via API.

  • transactions array will be empty
  • totalReceivedAmount will be "0.00"

2. Payment Partially Paid (Status: OPEN)

Sent when payment receives funds but less than requested amount.

  • transactions array contains received transaction(s)
  • totalReceivedAmount < amount
  • Payment remains OPEN for additional transactions

3. Payment Completed (Status: COMPLETED)

Sent when payment receives full requested amount.

  • totalReceivedAmount >= amount
  • All required confirmations received

4. Payment Overpaid (Status: COMPLETED)

Sent when payment receives more than requested amount.

  • totalReceivedAmount > amount
  • Excess funds included in the payment

5. Payment Expired (Status: EXPIRED)

Sent when payment timeout is reached without full payment.

  • No new transactions will be accepted

6. Payment Cancelled (Status: CANCELLED)

Sent if payment is manually cancelled.

7. AML Check Failed (Status: AML_CHECK_FAILED)

Sent when payment fails anti-money laundering compliance check.

  • Payment cannot be completed
  • Funds may be frozen pending investigation

Required Response

Your server must respond with:

  • HTTP Status: 200 OK
  • Body: Empty or simple acknowledgment

Example successful response:

HTTP/1.1 200 OK
Content-Length: 0

HMAC Signature Verification

Always verify the webhook authenticity using the X-HMAC header:

Node.js Example

import crypto from 'crypto';

function verifyWebhook(body, signature, secretKey) {
  const expectedSignature = crypto
    .createHmac('sha256', secretKey)
    .update(JSON.stringify(body), 'utf8')
    .digest('hex');
  
  return signature === expectedSignature;
}

// In your webhook handler
app.post('/webhooks/payment', (req, res) => {
  const signature = req.headers['x-hmac'];
  const isValid = verifyWebhook(req.body, signature, process.env.HMAC_SECRET);
  
  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the payment update
  const payment = req.body;
  
  switch(payment.status) {
    case 'COMPLETED':
      // Mark order as paid
      updateOrderStatus(payment.invoice, 'PAID');
      break;
    case 'EXPIRED':
      // Handle expired payment
      updateOrderStatus(payment.invoice, 'PAYMENT_EXPIRED');
      break;
    case 'AML_CHECK_FAILED':
      // Flag for manual review
      flagOrderForReview(payment.invoice);
      break;
  }
  
  res.status(200).send();
});

Handling Partial Payments

When a payment is partially paid, you'll receive a webhook with:

  • Status remains OPEN
  • totalReceivedAmount shows the current total
  • transactions array contains all received transactions

Example partial payment handling:

if (payment.status === 'OPEN' && parseFloat(payment.totalReceivedAmount) > 0) {
  const percentPaid = (parseFloat(payment.totalReceivedAmount) / parseFloat(payment.amount)) * 100;
  console.log(`Payment ${percentPaid.toFixed(2)}% complete`);
  
  // Notify customer about partial payment
  sendPartialPaymentNotification(payment.customer.email, payment.totalReceivedAmount, payment.amount);
}

Retry Policy

If your server doesn't respond with 200 OK:

  • ALPPAY will retry the webhook up to 5 times
  • Retry intervals: 1 minute, 5 minutes, 30 minutes, 2 hours, 12 hours
  • After 5 failed attempts, the webhook is marked as failed

Best Practices

  1. Always verify HMAC signature before processing
  2. Respond quickly (within 5 seconds) to avoid timeouts
  3. Use idempotent processing - same webhook may be sent multiple times
  4. Handle all status types including partial payments
  5. Store payment state to track payment progression
  6. Log all webhooks for debugging and reconciliation
  7. Implement proper error handling for webhook processing failures

Common Integration Patterns

Order Status Management

function processPaymentWebhook(payment) {
  switch(payment.status) {
    case 'OPEN':
      if (payment.totalReceivedAmount === '0.00') {
        // New payment created
        logPaymentCreated(payment);
      } else {
        // Partial payment received
        updateOrderPartialPayment(payment);
      }
      break;
    
    case 'COMPLETED':
      // Full payment received
      markOrderAsPaid(payment);
      sendConfirmationEmail(payment.customer.email);
      break;
    
    case 'EXPIRED':
      // Payment window closed
      cancelOrder(payment.invoice);
      break;
    
    case 'AML_CHECK_FAILED':
      // Compliance issue
      flagForManualReview(payment);
      notifyComplianceTeam(payment);
      break;
  }
}

Testing Webhooks

For testing webhook integration:

  1. Use ngrok or similar service to expose local endpoints
  2. Create test payments in sandbox environment
  3. Monitor webhook delivery in ALPPAY dashboard
  4. Test all status scenarios including partial payments