Перейти к основному содержимому

CoinPayments Integration

Overview

The CoinPayments integration allows users to make payments using various cryptocurrencies. This document outlines the implementation details, webhook handling, and subscription management for CoinPayments in our system.

Configuration

Environment Variables

Add these configurations to your application.yml:

coinpayment:
merchant-id: YOUR_MERCHANT_ID
ipn:
url: https://your-domain.com/api/webhook/coinpayment/ipn
secret: YOUR_IPN_SECRET
key:
public: YOUR_PUBLIC_KEY
private: YOUR_PRIVATE_KEY

API Endpoints

Create Payment

Creates a new cryptocurrency payment transaction.

mutation coinpaymentCreatePayment(
category: PaymentCategory!
groupId: Int
moreLoginCount: Int
coin: String!
): CoinPaymentResponse

Parameters:

  • category: Payment category (GROUP, MORE_LOGIN, BUY_CREDIT)
  • groupId: ID of the subscription group
  • moreLoginCount: Number of additional logins
  • coin: Cryptocurrency code (e.g., "BTC", "ETH")

Response:

interface CoinPaymentResponse {
id: number;
txn_id: string;
address: string;
amount: string;
checkout_url: string;
qrcode_url: string;
status_url: string;
confirms_needed: string;
timeout: number;
error?: string;
}

Webhook Endpoint

POST /api/webhook/coinpayment/ipn/{paymentId}

Receives payment status updates from CoinPayments.

Headers:

  • HMAC: Signature for request verification

Webhook Payload:

{
"address": "payment_address",
"amount": "payment_amount",
"confirms": "number_of_confirms",
"currency": "crypto_currency",
"status": "payment_status",
"txn_id": "transaction_id"
}

Status Codes:

  • 0: Pending
  • 1: Payment received but unconfirmed
  • 100: Payment confirmed and completed
  • -1: Payment cancelled/timed out

Implementation Example

Creating a Payment

const createPayment = async (groupId, coin) => {
const response = await graphqlClient.mutate({
mutation: CREATE_COINPAYMENT,
variables: {
category: "GROUP",
groupId: groupId,
coin: coin,
},
});

return response.data.coinpaymentCreatePayment;
};

Handling the Payment Response

const handlePaymentCreation = async () => {
const payment = await createPayment(groupId, "BTC");

if (payment.error) {
console.error("Payment creation failed:", payment.error);
return;
}

// Redirect to checkout URL or show QR code
window.location.href = payment.checkout_url;
// OR
displayQRCode(payment.qrcode_url);
};

Security Considerations

  1. HMAC Verification: Always verify webhook signatures using the IPN secret:
boolean verifyHmacSignature(Map<String, String> payload, String receivedHmac, String secret) {
// HMAC-SHA512 verification implementation
}
  1. Payment Validation: Verify transaction amounts and statuses:
validateCoinPayment(Payment payment) {
if (payment.getStatus() != PaymentStatus.SUCCEEDED) {
throw new PaymentException("Payment not completed");
}
}

Subscription Flow

  1. User initiates cryptocurrency payment
  2. System creates payment record and CoinPayments transaction
  3. User sends payment to provided address
  4. CoinPayments sends webhook notifications about payment status
  5. System validates and processes payment once confirmed
  6. Subscription is activated after successful payment

Error Handling

Common error scenarios and their handling:

Error CodeDescriptionAction
400Invalid parametersCheck request parameters
401Authentication failedVerify API keys
402Payment failedCheck payment status
500Server errorContact support

Best Practices

  1. Always store transaction IDs for reference
  2. Implement proper error handling
  3. Validate payment amounts before fulfillment
  4. Monitor payment timeouts
  5. Implement automatic cleanup for expired payments
  6. Use webhook retries for failed notifications

Debugging

To help with debugging, enable debug logging:

logging:
level:
com.orbvpn.api.service.payment.coinpayment: DEBUG

Monitor payments using the debug logs:

tail -f application.log | grep "CoinPayment"

Rate Limits

  • API calls: 600 requests per hour
  • Webhook retries: 3 attempts with exponential backoff
  • Payment timeout: 24 hours