English Docs

Getting Started

Introduction, authentication, payment flows, webhook handling, and code examples for integrating with JovePay.

JovePay API

JovePay is a non-custodial cryptocurrency payment processing platform. Accept payments in a wide range of cryptos and get them instantly converted and paid out to your wallet. Keeping it simple – no excess.

Authentication

To use the JovePay API:

  1. Sign up at jovepay.io.
  2. Specify your payout wallet.
  3. Generate an API key and IPN secret key.

Note: The IPN secret key is only fully displayed upon creation. Save it after generation.

Standard e-commerce flow for JovePay

  1. API: Check API availability:
    GET /v1/status
  2. API (Optional): Get available payment currencies:
    GET /v1/currencies
  3. UI: Customer selects item(s) for purchase (gets total price).
  4. UI: Customer selects payment currency.
  5. API: Get minimum payment amount for currency pair:
    GET /v1/min-amount
  6. API: Estimate total amount in crypto:
    GET /v1/estimate
    (Ensure it's above the minimum)
  7. API: Create payment:
    POST /v1/payment
    (Get deposit address)
  8. UI: Customer pays to generated deposit address.
  9. Backend/UI: Track payment status via:
    • IPN callbacks
    • GET /v1/payment/{payment_id}
  10. API: Retrieve list of payments:
    GET /v1/payment

All info is also visible in your JovePay account.


Alternative Flow (Using Invoices)

Instead of a deposit address, you can generate an invoice for your customer.

  1. API: Create invoice:
    POST /v1/invoice
    (Set success_url to redirect on success)
  2. UI: Display invoice URL or redirect user to invoice.
  3. JovePay: Handles payment, redirects back to your site (if configured).
  4. Track payment status as above.

Instant Payment Notifications (IPN)

IPN webhooks notify you when transaction status updates.

To use IPN:

  1. Generate and save the IPN Secret key (Dashboard → Payment Settings).
  2. Insert your webhook URL in the create_payment request's ipn_callback_url parameter. We'll send payment status updates here.
    • We cannot send callbacks to localhost unless it has a dedicated IP address.

  3. Ensure your server and firewall allows requests from our IPs (contact [email protected] if needed).
  4. We'll POST updates to your ipn_callback_url.
    • Header: x-jovepay-sig (signature)
    • Body: JSON (similar to payment status)

Verifying IPN requests

Sort keys and encode as JSON, then sign with your IPN key (sha512/HMAC). Compare signature with x-jovepay-sig header.

Node.js Example

function sortObject(obj) {
  return Object.keys(obj).sort().reduce(
    (result, key) => {
      result[key] = (obj[key] && typeof obj[key] === 'object') ? sortObject(obj[key]) : obj[key];
      return result;
    }, {}
  );
}

const hmac = crypto.createHmac('sha512', notificationsKey);
hmac.update(JSON.stringify(sortObject(params)));
const signature = hmac.digest('hex');

PHP Example

function tksort(&$array) {
  ksort($array);
  foreach(array_keys($array) as $k) {
    if(gettype($array[$k])=="array") {
      tksort($array[$k]);
    }
  }
}

function check_ipn_request_is_valid() {
  $error_msg = "Unknown error";
  $auth_ok = false;
  $request_data = null;
  if (isset($_SERVER['HTTP_X_JOVEPAY_SIG']) && !empty($_SERVER['HTTP_X_JOVEPAY_SIG'])) {
    $recived_hmac = $_SERVER['HTTP_X_JOVEPAY_SIG'];
    $request_json = file_get_contents('php://input');
    $request_data = json_decode($request_json, true);
    tksort($request_data);
    $sorted_request_json = json_encode($request_data, JSON_UNESCAPED_SLASHES);
    if ($request_json !== false && !empty($request_json)) {
      $hmac = hash_hmac("sha512", $sorted_request_json, trim($this->ipn_secret));
      if ($hmac == $recived_hmac) {
        $auth_ok = true;
      } else {
        $error_msg = 'HMAC signature does not match';
      }
    } else {
      $error_msg = 'Error reading POST data';
    }
  } else {
    $error_msg = 'No HMAC signature sent.';
  }
}

Python Example

import json
import hmac
import hashlib

def np_signature_check(np_secret_key, np_x_signature, message):
    sorted_msg = json.dumps(message, separators=(',', ':'), sort_keys=True)
    digest = hmac.new(
        str(np_secret_key).encode(), 
        f'{sorted_msg}'.encode(),
        hashlib.sha512
    )
    signature = digest.hexdigest()
    if signature == np_x_signature:
        return
    else:
        print("HMAC signature does not match")

Tip: You’ll get notification for every event. Always test your endpoint before going live.

Recurrent payment notifications

If delivery fails, we'll retry based on your dashboard settings.


Webhook Examples

Payment Webhook

{
  "payment_id": 123456789,
  "parent_payment_id": 987654321,
  "invoice_id": null,
  "payment_status": "finished",
  "pay_address": "address",
  "payin_extra_id": null,
  "price_amount": 1,
  "price_currency": "usd",
  "pay_amount": 15,
  "actually_paid": 15,
  "actually_paid_at_fiat": 0,
  "pay_currency": "trx",
  "order_id": null,
  "order_description": null,
  "purchase_id": "123456789",
  "outcome_amount": 14.8106,
  "outcome_currency": "trx",
  "payment_extra_ids": null,
  "fee": {
    "currency": "btc",
    "depositFee": 0.09853637216235617,
    "withdrawalFee": 0,
    "serviceFee": 0
  }
}

Withdrawal Webhook

{
  "id": "123456789",
  "batch_withdrawal_id": "987654321",
  "status": "CREATING",
  "error": null,
  "currency": "usdttrc20",
  "amount": "50",
  "address": "address",
  "fee": null,
  "extra_id": null,
  "hash": null,
  "ipn_callback_url": "callback_url",
  "created_at": "2023-07-27T15:29:40.803Z",
  "requested_at": null,
  "updated_at": null
}

Custodial recurring payment

{
  "id":"1234567890",
  "status":"FINISHED",
  "currency":"trx",
  "amount":"12.171365564140688",
  "ipn_callback_url":"callback_url",
  "created_at":"2023-07-26T14:20:11.531Z",
  "updated_at":"2023-07-26T14:20:21.079Z"
}

Handling Repeated & Wrong-Asset Deposits

Repeated Deposits

  • Extra payments to the same deposit address (parent_payment_id links to the original).
  • Marked "Re-deposit" in dashboard.
  • Track parent_payment_id in IPN to avoid providing service for partial/underpayments.
  • Not recommended to automate fulfillment on repeated-deposit status.

Note: All repeated deposits are converted to the payment’s original asset.

Wrong-Asset Deposits

  • User sends wrong network/asset (but supported).
  • Labeled “Wrong Asset” in dashboard.
  • Usually requires manual resolution.
  • You may enable auto-processing in dashboard settings, but use with caution.
  • Always validate amount and asset type from IPN.

Developer SDKs & Packages


Sample API Calls

Check API status

curl --location 'https://api.jovepay.io/v1/status'

Successful response:

{
  "message": "OK"
}

Authenticate and obtain JWT

curl --location 'https://api.jovepay.io/v1/auth' \
  --header 'Content-Type: application/json' \
  --data '{
      "email": "your_email",
      "password": "your_password"
  }'

Successful response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Use this token as Bearer for all authenticated endpoints:

Authorization: Bearer <token>

For more methods and detailed flows, see the JovePay official API documentation and your developer dashboard.

On this page