### Run Bitcoin Core in Testnet Mode (Windows) Source: https://docs.paymento.io/accept-crypto-payments/testing-and-simulation/creating-a-testnet-wallet This command starts the Bitcoin Core client in testnet mode with pruning enabled to minimize disk space. Ensure Bitcoin Core is installed and the command prompt is in the installation directory. ```batch .\bitcoin-qt.exe -testnet -prune=550 ``` -------------------------------- ### Run Electrum in Testnet Mode (Windows) Source: https://docs.paymento.io/accept-crypto-payments/testing-and-simulation/creating-a-testnet-wallet This command launches the Electrum wallet with the testnet flag enabled. Make sure Electrum is installed and the command prompt is in the Electrum installation folder. ```batch .\electrum-4.0.6.exe --testnet ``` -------------------------------- ### Callback Example Request Source: https://docs.paymento.io/api-documention/payment-callback This cURL command illustrates an example of a POST request received from Paymento, including the necessary headers and the JSON body containing payment details. This can be used for testing and understanding the structure of incoming callbacks. ```curl curl -X POST https://yoursite.com/shop/payment-result -H 'Accept: application/json' -H 'HMAC_SHA256_SIGNATURE: vBvDwCix13cq7anuf5eleiOXjFApBLxEWC2G2lgnJTU=' -H 'Content-Type: application/json' -d '{"Token":"d1179e54e58d4e51a285a5c659a2b7ef","PaymentId":20016,"OrderId":"etp-3900","OrderStatus":3,"AdditionalData":[]}' ``` -------------------------------- ### Generate HMAC-SHA256 Signatures for Webhooks Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide Provides code examples for generating the HMAC-SHA256 signature required for webhook verification across various programming languages. This is crucial for securing your webhook endpoints by ensuring requests originate from Paymento. ```javascript const crypto = require('crypto'); const signature = crypto .createHmac('sha256', secretKey) .update(rawBody) .digest('hex'); ``` ```python import hmac import hashlib signature = hmac.new( secret_key.encode('utf-8'), raw_body.encode('utf-8'), hashlib.sha256 ).hexdigest() ``` ```php $signature = hash_hmac('sha256', $rawBody, $secretKey); ``` ```csharp using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey)); var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(rawBody)); var signature = BitConverter.ToString(hash).Replace("-", "").ToLower(); ``` ```ruby require 'openssl' signature = OpenSSL::HMAC.hexdigest('sha256', secret_key, raw_body) ``` ```go import "crypto/hmac" import "crypto/sha256" import "encoding/hex" mac := hmac.New(sha256.New, []byte(secretKey)) mac.Write([]byte(rawBody)) signature := hex.EncodeToString(mac.Sum(nil)) ``` ```java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; Mac mac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"); mac.init(secretKeySpec); byte[] hash = mac.doFinal(rawBody.getBytes()); String signature = Hex.encodeHexString(hash); ``` -------------------------------- ### Handling Events Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide Process different event types received from Paymento to automate business logic, such as activating subscriptions or notifying users. ```APIDOC ## Handling Events ### Description Paymento sends various events that allow you to automate actions within your application based on payment statuses and subscription changes. ### Event Types and Use Cases | Event | Description | | ---------------------------- | --------------------------------------------- | | `payment_link.paid` | Trigger actions when a payment link is paid. | | `payment_link.failed` | Handle cases where a payment link fails. | | `payment_link.expired` | Respond when a payment link expires unpaid. | | `subscription.renewed` | Automate subscription renewals. | | `subscription.reminder_sent` | Log or track reminder notifications sent. | | `subscription.grace_expired` | Revoke access or take action after grace period.| ### Example: Handling Event Types #### Node.js ```javascript const event = req.body; // Assuming req.body is already parsed JSON // First, verify the signature (as shown in the Signature Verification section) switch (event.event.type) { case 'payment_link.paid': // Example: Activate a user's subscription activateSubscription(event.customer.email, event.paymentLink.id); break; case 'payment_link.deferred': // Example: Suspend a user's subscription if payment is deferred suspendSubscription(event.customer.email, event.paymentLink.id); break; case 'subscription.renewed': // Example: Extend subscription duration extendSubscription(event.customer.email, event.subscription.id); break; case 'subscription.grace_expired': // Example: Revoke access if grace period expires without payment revokeAccess(event.customer.email, event.subscription.id); break; default: console.log(`Received unhandled event type: ${event.event.type}`); } // Respond with 200 OK to acknowledge receipt res.status(200).json({ received: true }); function activateSubscription(email, paymentLinkId) { console.log(`Activating subscription for ${email} due to payment link ${paymentLinkId}`); // Your logic here } function suspendSubscription(email, paymentLinkId) { console.log(`Suspending subscription for ${email} due to deferred payment link ${paymentLinkId}`); // Your logic here } function extendSubscription(email, subscriptionId) { console.log(`Extending subscription ${subscriptionId} for ${email}`); // Your logic here } function revokeAccess(email, subscriptionId) { console.log(`Revoking access for subscription ${subscriptionId} for ${email}`); // Your logic here } ``` ### Checklist for Going Live Before deploying to production, ensure the following: * [ ] Your webhook endpoint uses HTTPS. * [ ] Signature verification is correctly implemented and robust. * [ ] Your endpoint responds with `200 OK` within 5 seconds. * [ ] You handle idempotency by checking the `event.id` to prevent processing the same event multiple times. * [ ] All incoming webhook requests are logged for debugging and auditing. * [ ] Your webhook secret key is stored securely, preferably as an environment variable. * [ ] Comprehensive error handling is in place for potential issues. * [ ] Your webhook has been thoroughly tested using the Paymento test webhook feature. ``` -------------------------------- ### Redirect to Payment Gateway Source: https://docs.paymento.io/api-documention/payment-request This example illustrates how to construct the URL to redirect a customer to the Paymento gateway after a successful payment request. The token obtained from the API response is appended to the base gateway URL. ```text https://app.paymento.io/gateway?token=TOKEN_HERE ``` -------------------------------- ### Signature Verification Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide Implement signature verification using your webhook secret key to ensure that incoming webhook requests are genuinely from Paymento and have not been tampered with. ```APIDOC ## Signature Verification ### Description Verifying the signature of incoming webhook requests is crucial for security. It ensures that the data received originates from Paymento and has not been altered in transit. ### Method This is a process applied to the incoming `POST /webhook` request. ### Steps 1. Retrieve the `x-paymento-signature` header from the incoming request. 2. Obtain your `webhook secretkey` from your Paymento settings. 3. Construct the raw request body (ensure no modifications or parsing have occurred yet). 4. Compute an HMAC-SHA256 hash of the raw request body using your `webhook secretkey`. 5. Compare the computed hash with the signature provided in the header. If they do not match, reject the request with a `400 Bad Request` status. ### Code Samples #### Node.js ```javascript const crypto = require('crypto'); const signature = req.headers['x-paymento-signature']; const secretKey = 'YOUR_MERCHANT_SECRET_KEY'; // From Paymento dashboard const rawBody = req.rawBody; // Ensure you capture the raw request body const computed = crypto .createHmac('sha256', secretKey) .update(rawBody) .digest('hex'); if (signature !== computed) { return res.status(401).send('Invalid signature'); } // Proceed with handling the request ``` #### Python ```python import hmac import hashlib signature = request.headers.get('x-paymento-signature') secret_key = 'YOUR_MERCHANT_SECRET_KEY' raw_body = request.data # Assuming you can access the raw body computed = hmac.new( secret_key.encode('utf-8'), raw_body.encode('utf-8'), hashlib.sha256 ).hexdigest() if not hmac.compare_digest(signature, computed): return Response('Invalid signature', status=401) # Proceed with handling the request ``` #### PHP ```php $signature = $_SERVER['HTTP_X_PAYMENTO_SIGNATURE']; $secretKey = 'YOUR_MERCHANT_SECRET_KEY'; // From Paymento dashboard $rawBody = file_get_contents('php://input'); $computed = hash_hmac('sha256', $rawBody, $secretKey); if (!hash_equals($signature, $computed)) { http_response_code(401); echo 'Invalid signature'; exit; } // Proceed with handling the request ``` #### C# ```csharp using System.Security.Cryptography; using System.Text; var signature = Request.Headers["x-paymento-signature"]; var secretKey = "YOUR_MERCHANT_SECRET_KEY"; // From Paymento dashboard using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey)); var rawBodyBytes = Encoding.UTF8.GetBytes(await Request.ReadRawBodyAsync()); // Assuming a method to read raw body var hash = hmac.ComputeHash(rawBodyBytes); var computed = BitConverter.ToString(hash).Replace("-", "").ToLower(); if (signature != computed) { return StatusCode(401, "Invalid signature"); } // Proceed with handling the request ``` #### Ruby ```ruby require 'openssl' signature = request.headers['x-paymento-signature'] secret_key = 'YOUR_MERCHANT_SECRET_KEY' # From Paymento dashboard raw_body = request.body.read computed = OpenSSL::HMAC.hexdigest('sha256', secret_key, raw_body) unless Rack::Utils.secure_compare(signature, computed) head :unauthorized, text: 'Invalid signature' return end # Proceed with handling the request ``` #### Go ```go import ( "crypto/hmac" "crypto/sha256" "encoding/hex" "net/http" ) func VerifySignature(r *http.Request, secretKey string) bool { signature := r.Header.Get("x-paymento-signature") bodyBytes, _ := io.ReadAll(r.Body) // Ensure to reset the body reader if needed later r.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) mac := hmac.New(sha256.New, []byte(secretKey)) mac.Write(bodyBytes) computed := hex.EncodeToString(mac.Sum(nil)) return signature == computed } // In your handler: // if !VerifySignature(r, "YOUR_MERCHANT_SECRET_KEY") { // http.Error(w, "Invalid signature", http.StatusUnauthorized) // return // } // Proceed with handling the request ``` #### Java ```java import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Hex; import java.nio.charset.StandardCharsets; public class WebhookVerifier { public String verify(String rawBody, String signature) throws Exception { String secretKey = "YOUR_MERCHANT_SECRET_KEY"; // From Paymento dashboard Mac mac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"); mac.init(secretKeySpec); byte[] hash = mac.doFinal(rawBody.getBytes(StandardCharsets.UTF_8)); String computed = Hex.encodeHexString(hash); if (!signature.equals(computed)) { throw new RuntimeException("Invalid signature"); } return "Signature valid"; } } // In your handler: // WebhookVerifier verifier = new WebhookVerifier(); // try { // verifier.verify(rawBody, signature); // } catch (Exception e) { // response.setStatus(401); // Unauthorized // return; // } // Proceed with handling the request ``` ``` -------------------------------- ### Get Payment Settings API Source: https://docs.paymento.io/api-documention/additional-apis/manage-payment-settings Retrieves the current payment settings, including the callback URL and HTTP method. ```APIDOC ## GET /v1/payment/settings ### Description Retrieves the current payment settings, including the callback URL and HTTP method for receiving payment status updates. ### Method GET ### Endpoint https://api.paymento.io/v1/payment/settings ### Parameters #### Headers - **Api-Key** (string) - Required - Your Merchant API Key - **Content-Type** (string) - Required - application/json - **Accept** (string) - Required - text/plain ### Response #### Success Response (200) - **success** (boolean) - Indicates if the operation was successful. - **message** (string) - Any message related to the operation. - **body** (object) - Contains the current settings. - **apiEndpointPath** (string) - The configured callback URL. - **httpMethod** (integer) - The configured HTTP method (1 for POST, 2 for PUT). #### Response Example ```json { "success": true, "message": "", "body": { "apiEndpointPath ": "https://yoursite.com/api/paymento/payment-status", "httpMethod": 1 } } ``` #### Error Response (400) - **error** (string) - Description of the error. #### Error Response Example ```json { "error": "Invalid request" } ``` ``` -------------------------------- ### JavaScript: Correct Signature Calculation for Paymento.io Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/troubleshooting This snippet demonstrates the correct method for calculating a signature in JavaScript using the raw request body, essential for verifying requests from Paymento.io. It highlights the common mistake of using parsed JSON instead of the raw body. ```javascript const crypto = require('crypto'); // Assuming secretKey and req.rawBody are available // const secretKey = "YOUR_SECRET_KEY"; // const rawBody = "{\"event\": \"payment.succeeded\", \"data\": {}}"; // Example raw body // ❌ Wrong - Using parsed JSON // const signatureWrong = crypto // .createHmac('sha256', secretKey) // .update(JSON.stringify(JSON.parse(rawBody))) // ❌ Don't stringify parsed JSON // .digest('hex'); // ✅ Correct - Using raw body const signatureCorrect = crypto .createHmac('sha256', secretKey) .update(rawBody) // ✅ Use raw body .digest('hex'); console.log('Correct Signature:', signatureCorrect); ``` -------------------------------- ### POST /webhook Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide Paymento sends a POST request to your configured webhook URL when events occur. It includes the event data in the request body and an HMAC-SHA256 signature in the `x-paymento-signature` header for verification. ```APIDOC ## POST /webhook ### Description Receives event notifications from Paymento. Requires signature verification to ensure data integrity and authenticity. ### Method POST ### Endpoint /webhook ### Parameters #### Headers - **x-paymento-signature** (string) - Required - The HMAC-SHA256 signature of the raw request body. - **content-type** (string) - Required - Must be `application/json`. #### Request Body - **event** (object) - Required - Contains details about the event. - **id** (string) - Required - Unique ID for the event. - **type** (string) - Required - The type of event (e.g., `payment_link.paid`). - **createdAt** (string) - Required - ISO-8601 timestamp of event creation. - **apiVersion** (string) - Required - The API version used. - **paymentLink** (object) - Required - Details about the payment link. - **id** (string) - Required - Unique ID for the payment link. - **title** (string) - Optional - Title of the payment link. - **description** (string) - Optional - Description of the payment link. - **status** (string) - Required - Current status of the payment link (`paid` or `deferred`). - **type** (string) - Required - Type of payment link (`one_time` or `scheduled`). - **createdAt** (string) - Required - ISO-8601 timestamp of creation. - **paidAt** (string | null) - Optional - ISO-8601 timestamp when paid, or null. - **url** (string) - Required - The URL of the payment link. - **customer** (object) - Required - Information about the customer. - **email** (string) - Required - Customer's email address. - **name** (string) - Optional - Customer's name. - **metadata** (object) - Optional - Custom metadata associated with the customer. - **order_id** (string) - Optional - Order ID. - **payment_id** (string) - Optional - Payment ID. - **merchant** (object) - Required - Information about the merchant. - **id** (string) - Required - Merchant's unique ID. - **name** (string) - Required - Merchant's name. ### Request Example ```json { "event": { "id": "evt_abc123", "type": "payment_link.paid", "createdAt": "2023-10-27T10:00:00Z", "apiVersion": "v1" }, "paymentLink": { "id": "pl_xyz789", "title": "Example Product", "description": "Purchase of Example Product", "status": "paid", "type": "one_time", "createdAt": "2023-10-26T09:00:00Z", "paidAt": "2023-10-27T09:55:00Z", "url": "https://pay.paymento.io/...'" }, "customer": { "email": "customer@example.com", "name": "John Doe", "metadata": { "order_id": "ORD-001" } }, "merchant": { "id": "merch_12345", "name": "My Awesome Store" } } ``` ### Response #### Success Response (200) Returns `200 OK` to acknowledge receipt of the webhook. The response body can be empty or contain a simple confirmation. #### Response Example ```json { "received": true } ``` ### Error Handling - Return `400 Bad Request` if the signature verification fails. - Return `500 Internal Server Error` for other processing issues. - Ensure responses are sent within 5 seconds to avoid timeouts. ``` -------------------------------- ### Handle Payment Events in Node.js Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide Processes incoming webhook events from Paymento by examining the event type. This allows for automated actions based on payment outcomes, such as activating a subscription for a 'payment_link.paid' event or suspending it for a 'payment_link.deferred' event. Ensure to respond with a 200 status code to acknowledge receipt. ```javascript const event = req.body; switch (event.event.type) { case 'payment_link.paid': // Customer paid successfully activateSubscription(event.customer.email); break; case 'payment_link.deferred': // Payment was not made on time suspendSubscription(event.customer.email); break; } res.status(200).json({ received: true }); ``` -------------------------------- ### Get Payment Settings API Source: https://docs.paymento.io/api-documention/additional-apis/manage-payment-settings Retrieves your current payment settings, including the configured IPN URL and HTTP method. Requires an API key. Returns the settings in a JSON response or an error. ```json { "success": true, "message": "", "body": { "apiEndpointPath ": "https://yoursite.com/api/paymento/payment-status", "httpMethod": 1 } } ``` ```json { "error": "Invalid request" } ``` -------------------------------- ### Get List of Accepted Coins Source: https://docs.paymento.io/api-documention/additional-apis/get-list-of-accepted-coins Retrieves a list of cryptocurrencies that your merchant account is currently set up to accept. This can be used to dynamically update payment options. ```APIDOC ## GET /v1/payment/coins ### Description Retrieves a list of cryptocurrencies that your merchant account is currently set up to accept. This can be particularly useful for dynamically updating your payment options based on your current Paymento settings. ### Method GET ### Endpoint https://api.paymento.io/v1/payment/coins ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example None ### Response #### Success Response (200) - **success** (boolean) - Indicates if the request was successful. - **message** (string) - An optional message associated with the response. - **body** (array) - A list of accepted coins. - **name** (string) - The full name of the cryptocurrency. - **shortcut** (string) - The shortcut or symbol for the cryptocurrency. #### Response Example ```json { "success": true, "message": "", "body": [ { "name": "bitcoin", "shortcut": "btc" }, { "name": "ethereum", "shortcut": "eth" } ] } ``` #### Error Response (400) - **error** (string) - Description of the error. #### Error Response Example ```json { "error": "Invalid request" } ``` ``` -------------------------------- ### Add Sepolia Testnet to MetaMask Source: https://docs.paymento.io/accept-crypto-payments/testing-and-simulation/creating-a-testnet-wallet This configuration adds the Sepolia testnet to your MetaMask wallet, enabling you to interact with the Ethereum test network. Manual addition requires specific network details like RPC URL and Chain ID. ```javascript { "chainName": "Sepolia Testnet", "rpcUrl": "https://rpc.sepolia.org", "chainId": 11155111, "nativeCurrency": { "name": "ETH", "symbol": "ETH", "decimals": 18 } } ``` -------------------------------- ### Get Accepted Coins List (API) Source: https://docs.paymento.io/api-documention/additional-apis/get-list-of-accepted-coins This API endpoint retrieves a list of cryptocurrencies your merchant account accepts. It requires an API key in the headers and returns a JSON object containing the list of coins or an error message. ```bash curl -X GET \ https://api.paymento.io/v1/payment/coins \ -H 'Api-Key: Your Merchant API Key' \ -H 'Content-Type: application/json' \ -H 'Accept: text/plain' ``` ```json { "success": true, "message": "", "body": [ { "name": "bitcoin", "shortcut": "btc" }, { "name": "ethereum", "shortcut": "eth" } ] } ``` ```json { "error": "Invalid request" } ``` -------------------------------- ### Customer Object Description Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/integration-reference Outlines the structure and fields of the `customer` object, containing customer details. ```APIDOC ## Customer Object ### Description Represents a customer making a payment. ### Fields - **`email`** (string) - Customer email address. - **`name`** (string) - Customer name. - **`metadata`** (object) - Additional customer metadata (optional). - **`metadata.order_id`** (string?) - Order ID if available. - **`metadata.payment_id`** (string?) - Payment transaction ID if available. - **`metadata.scheduled_token`** (string?) - Scheduled payment token (for reminder/deferred events). - **`metadata.payment_link_url`** (string?) - Payment link URL (for reminder events). - **`metadata.due_date`** (string?) - Due date in YYYY-MM-DD format (for scheduled payments). - **`metadata.grace_date`** (string?) - Grace period end date in YYYY-MM-DD format (if applicable). - **`metadata.telegram_username`** (string?) - Customer's Telegram username (if available). - **`metadata.telegram_user_id`** (string?) - Customer's Telegram user ID (only for Telegram integrations). ``` -------------------------------- ### Paymento IO Webhook HTTP Headers Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/integration-reference This snippet shows the required HTTP headers for authentication and tracking when receiving webhook requests from Paymento IO. Key headers include X-Paymento-Signature for verification, X-Paymento-Timestamp for request time, X-Paymento-Event-Id for event identification, and X-Paymento-Event-Type for the event's nature. ```http POST /your-webhook-endpoint HTTP/1.1 Host: your-server.com Content-Type: application/json X-Paymento-Signature: 9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b X-Paymento-Timestamp: 1699564800 X-Paymento-Event-Id: evt_a1b2c3d4e5f6g7h8i9j0 X-Paymento-Event-Type: payment_link.paid ``` -------------------------------- ### Event Object Description Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/integration-reference Describes the structure and fields of the `event` object, which represents an event within the Paymento system. ```APIDOC ## Event Object ### Description Represents an event within the Paymento system. ### Fields - **`id`** (string) - Unique identifier for this event (format: `evt_*`). - **`type`** (string) - Event type (see Event Types). - **`createdAt`** (string) - ISO 8601 timestamp when the event was created. - **`apiVersion`** (string) - Paymento API version used. ``` -------------------------------- ### Payment Link Object Description Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/integration-reference Details the structure and fields of the `paymentLink` object, used for representing payment links. ```APIDOC ## Payment Link Object ### Description Represents a payment link created within the Paymento system. ### Fields - **`id`** (string) - Unique payment link identifier. - **`title`** (string) - Payment link title. - **`description`** (string) - Payment link description. - **`status`** (string) - Current status: `"paid"`, `"deferred"`, or `"scheduled"`. - **`type`** (string) - Payment type: `"one_time"` or `"scheduled"`. - **`createdAt`** (string) - ISO 8601 timestamp when payment link was created. - **`paidAt`** (string?) - ISO 8601 timestamp when payment was completed (null if not paid). - **`url`** (string) - Public URL of the payment link. - **`integrationMetadata`** (object) - Integration metadata for external platforms (Telegram, Discord, etc.) - optional. ``` -------------------------------- ### Invalid Payment Request Response Source: https://docs.paymento.io/api-documention/payment-request This snippet shows an example of an error response from the Paymento API when the payment request is invalid. It typically returns a 400 status code and an error message indicating the issue. ```json { "error": "Invalid request" } ``` -------------------------------- ### HMAC-SHA256 Signature Verification (Pseudo-code) Source: https://docs.paymento.io/api-documention/payment-callback This pseudo-code demonstrates the process of verifying the HMAC-SHA256 signature sent in the callback headers. It involves calculating the signature from the raw payload using a secret key and comparing it with the received signature. This ensures the integrity and authenticity of the callback. ```pseudo-code // The signatures should match exactly. Here's a pseudo-code example: receivedSignature = headers['X-HMAC-SHA256-SIGNATURE'] payload = request.rawBody secretKey = "Your-Secret-Key-From-Paymento-Dashboard" calculatedSignature = uppercase(hmac_sha256(payload, secretKey)) isValid = (calculatedSignature == receivedSignature) ``` -------------------------------- ### Successful Payment Request Response Source: https://docs.paymento.io/api-documention/payment-request This is an example of a successful response from the Paymento API when a new payment request is created. It indicates success and provides a unique token that should be used to redirect the customer to the payment gateway. ```json { "success": true, "message": "", "body": "3256e147c6fe4d36a9341a5112ed2214" } ``` -------------------------------- ### Verify Paymento Webhook Signature in Node.js Source: https://docs.paymento.io/payment-links/webhooks-for-payment-links/quick-integration-guide Verifies the HMAC-SHA256 signature of an incoming webhook request to ensure its authenticity. It requires the request headers, raw request body, and your webhook secret key. This prevents unauthorized requests from being processed. ```javascript const crypto = require('crypto'); const signature = req.headers['x-paymento-signature']; const secretKey = 'YOUR_MERCHANT_SECRET_KEY'; // From Paymento dashboard const computed = crypto .createHmac('sha256', secretKey) .update(req.rawBody) .digest('hex'); if (signature !== computed) { return res.status(401).send('Invalid signature'); } ``` -------------------------------- ### Verify Payment with JSON Request Source: https://docs.paymento.io/api-documention/payment-verify This snippet demonstrates how to make a POST request to the Paymento API to verify a payment. It includes the necessary headers and a JSON body containing the payment token. The response indicates success or failure. ```bash curl -X POST \ https://api.paymento.io/v1/payment/verify \ -H 'Content-Type: application/json' \ -H 'Accept: text/plain' \ -H 'Api-key: Your Merchant API Key' \ -d '{ "token": "your_payment_token" }' ``` ```python import requests api_key = "Your Merchant API Key" url = "https://api.paymento.io/v1/payment/verify" headers = { "Content-Type": "application/json", "Accept": "text/plain", "Api-key": api_key } payload = { "token": "your_payment_token" } response = requests.post(url, headers=headers, json=payload) print(response.json()) ``` ```javascript const apiKey = "Your Merchant API Key"; const url = "https://api.paymento.io/v1/payment/verify"; const headers = { "Content-Type": "application/json", "Accept": "text/plain", "Api-key": apiKey }; const payload = { "token": "your_payment_token" }; fetch(url, { method: "POST", headers: headers, body: JSON.stringify(payload) }) .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error('Error:', error)); ```