VeyqoDEVELOPERS
DocumentationPOST Create Reference

SafeHaven Payments API

POST/safehaven/ussd-payment

Create Reference

Create Reference through this project environment’s SafeHaven account. Uses snake_case fields and NGN minor units. Requires payments:write.

POSThttps://api.veyqo.org/api/v1/safehaven/ussd-paymentIntegration guide
Use your sandbox environment to start. Understand error codes and payment statuses before handling a live payment.
Create Reference
curl --request POST "https://api.veyqo.org/api/v1/safehaven/ussd-payment" \
  --header "Authorization: Bearer $VEYQO_SECRET_KEY" \
  --header "Accept: application/json" \
  --header "Idempotency-Key: $OPERATION_IDEMPOTENCY_KEY" \
  --header "Content-Type: application/json" \
  --data '{
  "amount": 50000,
  "merchant_name": "example",
  "ussd_bank_code": "090286"
}'
{
  "success": true,
  "data": {
    "_id": "000000000000000000000001",
    "client": {
      "search_paid": false,
      "sub_account_creation": false,
      "long_term_virtual_account": false,
      "override_sub_account_limit": false,
      "allow_debit_account_info": false,
      "allow_debit_account_name": false,
      "indemnity_signed": false,
      "_id": "000000000000000000000001",
      "type": "example",
      "kyc_level": "example",
      "full_name": "example",
      "gender": "example",
      "date_of_birth": [],
      "email_address": "customer@example.com",
      "phone_number": "+2348000000000",
      "phone_number2": "+2348000000000",
      "bvn": "example",
      "nin": "example",
      "tin": "example",
      "contact_address": {
        "street": "example",
        "city": "example",
        "state": "example",
        "country": "example"
      },
      "identification_details": {
        "status": "Created",
        "type": "example",
        "number": "example"
      },
      "notification_settings": {
        "login_notification": false,
        "newsletter": false,
        "product_notification": false,
        "vas_notification": false,
        "webhook_notifcation": {
          "url": "https://example.com",
          "enabled": false
        }
      },
      "sub_account_prefix": "example",
      "is_blocked": false,
      "status": "Created",
      "referees": [],
      "is_deleted": false,
      "created_at": "example",
      "updated_at": "example",
      "identity_status": [],
      "__v": 0,
      "cba_client_id": "000000000000000000000001",
      "contract": "example",
      "virtual_account_limit": {
        "daily_limit": 0,
        "single_transaction_limit": 0,
        "allow_other_prefix": "example"
      },
      "documents": {
        "passport_url": "https://example.com",
        "id_card_url": "https://example.com",
        "signature_url": "https://example.com",
        "certificate_url": "https://example.com",
        "memat_url": "https://example.com",
        "board_resolution_url": "https://example.com",
        "utility_bill_url": "https://example.com"
      },
      "employment_information": [],
      "next_of_kin": []
    },
    "account": {
      "can_debit": false,
      "can_credit": false,
      "_id": "000000000000000000000001",
      "client": "example",
      "account_product": "example",
      "account_number": "0000000000",
      "account_name": "example",
      "account_type": "example",
      "currency_code": "example",
      "bvn": "example",
      "account_balance": 0,
      "book_balance": 0,
      "interest_balance": 0,
      "with_holding_tax_balance": 0,
      "status": "Created",
      "is_default": false,
      "nominal_annual_interest_rate": 0,
      "interest_compounding_period": "example",
      "interest_posting_period": "example",
      "interest_calculation_type": "example",
      "interest_calculation_days_in_year_type": "example",
      "min_required_opening_balance": 0,
      "lockin_period_frequency": 0,
      "lockin_period_frequency_type": "example",
      "allow_overdraft": false,
      "overdraft_limit": 0,
      "charge_with_holding_tax": false,
      "charge_value_added_tax": false,
      "charge_stamp_duty": false,
      "notification_settings": {
        "sms_notification": false,
        "email_notification": false,
        "email_monthly_statement": false,
        "sms_monthly_statement": false
      },
      "is_sub_account": false,
      "is_deleted": false,
      "created_at": "example",
      "updated_at": "example",
      "__v": 0,
      "cba_account_id": "000000000000000000000001"
    },
    "bank_code": "090286",
    "account_name": "example",
    "amount": 50000,
    "callback_url": "https://example.com",
    "status": "Created",
    "fees": 0,
    "settlement_account": {
      "bank_code": "090286",
      "account_number": "0000000000"
    },
    "external_reference": "order-1001",
    "is_deleted": false,
    "created_at": "example",
    "updated_at": "example",
    "__v": 0,
    "account_number": "0000000000",
    "details": {
      "reference": "order-1001",
      "amount": 50000,
      "transaction_id": "000000000000000000000001",
      "trace_id": "000000000000000000000001",
      "ussd_string": "example",
      "time_stamp": 0,
      "signature": "example"
    },
    "operation_id": "pso_01M6EB66SC61Q3RQYAN0693DGM"
  }
}

Illustrative examples. Replace IDs and environment variables with your own values. Keep secret keys on your server.

Headers

Authorizationstringrequired
Bearer <secret-key>. This key determines your project environment and must stay on your server.
Content-Typestringrequired
application/json
Acceptstringoptional
application/json
Idempotency-Keystringoptional
Persist one key for the operation and reuse it with the unchanged body on retries. Maximum 255 characters.

Endpoint

POST https://api.veyqo.org/api/v1/safehaven/ussd-payment

Server secret key required. Scope: payments:write. The key determines the project and environment; no project-selection header is accepted.

For each new operation, generate and persist one OPERATION_IDEMPOTENCY_KEY. Retry the unchanged request with that same key. Do not generate a new key on every retry.

Request body

amountintegerrequired
Amount in NGN minor units (kobo). Veyqo converts it to naira for SafeHaven. Minimum 1.
merchant_namestringrequired
See the JSON example.
ussd_bank_codestringrequired
See the JSON example.
settlement_accountobjectoptional
See the JSON example.
settlement_account.bank_codestringoptional
6 digits bank code. Must be `090286`
settlement_account.account_numberstringoptional
10 digits NUBAN account number

Response fields

_idstringoptional
See the JSON example.
clientobjectoptional
See the JSON example.
client.search_paidbooleanoptional
See the JSON example.
client.sub_account_creationbooleanoptional
See the JSON example.
client.long_term_virtual_accountbooleanoptional
See the JSON example.
client.override_sub_account_limitbooleanoptional
See the JSON example.
client.allow_debit_account_infobooleanoptional
See the JSON example.
client.allow_debit_account_namebooleanoptional
See the JSON example.
client.indemnity_signedbooleanoptional
See the JSON example.
client._idstringoptional
See the JSON example.
client.typestringoptional
See the JSON example.
client.kyc_levelstringoptional
See the JSON example.
client.full_namestringoptional
See the JSON example.
client.genderstringoptional
See the JSON example.
client.date_of_birthJSONoptional
See the JSON example.
client.email_addressstringoptional
See the JSON example.
client.phone_numberstringoptional
See the JSON example.
client.phone_number2stringoptional
See the JSON example.
client.bvnstringoptional
See the JSON example.
client.ninstringoptional
See the JSON example.
client.tinstringoptional
See the JSON example.
client.contact_addressobjectoptional
See the JSON example.
client.contact_address.streetstringoptional
See the JSON example.
client.contact_address.citystringoptional
See the JSON example.
client.contact_address.statestringoptional
See the JSON example.
client.contact_address.countrystringoptional
See the JSON example.
client.identification_detailsobjectoptional
See the JSON example.
client.identification_details.statusstringoptional
See the JSON example.
client.identification_details.typestringoptional
See the JSON example.
client.identification_details.numberstringoptional
See the JSON example.
client.notification_settingsobjectoptional
See the JSON example.
client.notification_settings.login_notificationbooleanoptional
See the JSON example.
client.notification_settings.newsletterbooleanoptional
See the JSON example.
client.notification_settings.product_notificationbooleanoptional
See the JSON example.
client.notification_settings.vas_notificationbooleanoptional
See the JSON example.
client.notification_settings.webhook_notifcationobjectoptional
See the JSON example.
client.sub_account_prefixstringoptional
See the JSON example.
client.is_blockedbooleanoptional
See the JSON example.
client.statusstringoptional
See the JSON example.
client.refereesarrayoptional
See the JSON example.
client.is_deletedbooleanoptional
See the JSON example.
client.created_atstringoptional
See the JSON example.
client.updated_atstringoptional
See the JSON example.
client.identity_statusarrayoptional
See the JSON example.
client.__vintegeroptional
See the JSON example.
client.cba_client_idstringoptional
See the JSON example.
client.contractstringoptional
See the JSON example.
client.virtual_account_limitobjectoptional
See the JSON example.
client.virtual_account_limit.daily_limitintegeroptional
See the JSON example.
client.virtual_account_limit.single_transaction_limitintegeroptional
See the JSON example.
client.virtual_account_limit.allow_other_prefixstringoptional
See the JSON example.
client.documentsobjectoptional
See the JSON example.
client.documents.passport_urlstringoptional
See the JSON example.
client.documents.id_card_urlstringoptional
See the JSON example.
client.documents.signature_urlstringoptional
See the JSON example.
client.documents.certificate_urlstringoptional
See the JSON example.
client.documents.memat_urlstringoptional
See the JSON example.
client.documents.board_resolution_urlstringoptional
See the JSON example.
client.documents.utility_bill_urlstringoptional
See the JSON example.
client.employment_informationobjectoptional
See the JSON example.
client.next_of_kinobjectoptional
See the JSON example.
accountobjectoptional
See the JSON example.
account.can_debitbooleanoptional
See the JSON example.
account.can_creditbooleanoptional
See the JSON example.
account._idstringoptional
See the JSON example.
account.clientstringoptional
See the JSON example.
account.account_productstringoptional
See the JSON example.
account.account_numberstringoptional
See the JSON example.
account.account_namestringoptional
See the JSON example.
account.account_typestringoptional
See the JSON example.
account.currency_codestringoptional
See the JSON example.
account.bvnstringoptional
See the JSON example.
account.account_balanceintegeroptional
Amount in NGN minor units (kobo).
account.book_balanceintegeroptional
Amount in NGN minor units (kobo).
account.interest_balanceintegeroptional
Amount in NGN minor units (kobo).
account.with_holding_tax_balanceintegeroptional
Amount in NGN minor units (kobo).
account.statusstringoptional
See the JSON example.
account.is_defaultbooleanoptional
See the JSON example.
account.nominal_annual_interest_rateintegeroptional
See the JSON example.
account.interest_compounding_periodstringoptional
See the JSON example.
account.interest_posting_periodstringoptional
See the JSON example.
account.interest_calculation_typestringoptional
See the JSON example.
account.interest_calculation_days_in_year_typestringoptional
See the JSON example.
account.min_required_opening_balanceintegeroptional
See the JSON example.
account.lockin_period_frequencyintegeroptional
See the JSON example.
account.lockin_period_frequency_typestringoptional
See the JSON example.
account.allow_overdraftbooleanoptional
See the JSON example.
account.overdraft_limitintegeroptional
See the JSON example.
account.charge_with_holding_taxbooleanoptional
See the JSON example.
account.charge_value_added_taxbooleanoptional
See the JSON example.
account.charge_stamp_dutybooleanoptional
See the JSON example.
account.notification_settingsobjectoptional
See the JSON example.
account.notification_settings.sms_notificationbooleanoptional
See the JSON example.
account.notification_settings.email_notificationbooleanoptional
See the JSON example.
account.notification_settings.email_monthly_statementbooleanoptional
See the JSON example.
account.notification_settings.sms_monthly_statementbooleanoptional
See the JSON example.
account.is_sub_accountbooleanoptional
See the JSON example.
account.is_deletedbooleanoptional
See the JSON example.
account.created_atstringoptional
See the JSON example.
account.updated_atstringoptional
See the JSON example.
account.__vintegeroptional
See the JSON example.
account.cba_account_idstringoptional
See the JSON example.
bank_codestringoptional
See the JSON example.
account_namestringoptional
See the JSON example.
amountintegeroptional
Amount in NGN minor units (kobo).
callback_urlstringoptional
See the JSON example.
statusstringoptional
See the JSON example.
feesintegeroptional
Amount in NGN minor units (kobo).
settlement_accountobjectoptional
See the JSON example.
settlement_account.bank_codestringoptional
See the JSON example.
settlement_account.account_numberstringoptional
See the JSON example.
external_referencestringoptional
See the JSON example.
is_deletedbooleanoptional
See the JSON example.
created_atstringoptional
See the JSON example.
updated_atstringoptional
See the JSON example.
__vintegeroptional
See the JSON example.
account_numberstringoptional
See the JSON example.
detailsobjectoptional
See the JSON example.
details.referencestringoptional
See the JSON example.
details.amountintegeroptional
Amount in NGN minor units (kobo).
details.transaction_idstringoptional
See the JSON example.
details.trace_idstringoptional
See the JSON example.
details.ussd_stringstringoptional
See the JSON example.
details.time_stampintegeroptional
See the JSON example.
details.signaturestringoptional
See the JSON example.
operation_idstringoptional
Veyqo pso_ operation ID. Save it to reconcile retries and match provider_service.updated events.
merchant_referencestringoptional
Your external_reference or payment_reference, if supplied. SafeHaven receives a globally unique Veyqo reference for supported writes.

Errors and recovery

CodeHTTPRecoveryRetry policy
VALIDATION_FAILED422Read error.details when present, correct the named fields and retry only after correction. Validation messages may describe state/capability errors without field details.No automatic retry.
INVALID_API_KEY401Use a current kc_test_ or kc_live_ secret key on /api/v1. Use a pk_test_ or pk_live_ publishable key only on browser checkout.After fixing credentials.
INSUFFICIENT_PERMISSION403Grant the required scope or use a suitably scoped key. Dashboard organization roles and staff permissions are separate.After permission changes.
RESOURCE_NOT_FOUND404Check the ID, project and environment. Do not guess another project’s IDs. An inactive payment link is also not-found.No blind retry.
PROVIDER_NOT_CONNECTED422Connect a provider, choose the project default, or explicitly pass provider. An account shared with another project still needs its own assignment here.After configuration changes.
PROVIDER_AUTHENTICATION_FAILED502The merchant must check/rotate the provider credentials in the dashboard. Do not expose those secrets to your application users.After credential correction; reconcile existing payment first.
PROVIDER_REQUEST_FAILED422Read the safe message, inspect the payment’s failure details and correct the request or provider account. Never repeatedly retry a business rejection.Only after resolving the cause.
PROVIDER_UNAVAILABLE503Check the existing payment and verify its state before starting another attempt. Retry safe reads with backoff; preserve operation identity for retried writes.Conditional: reconcile unknown outcomes first.
RATE_LIMIT_EXCEEDED429Honor Retry-After, use bounded exponential backoff with jitter, and reduce concurrent requests. Read X-RateLimit headers.Yes, after Retry-After; preserve write idempotency.
IDEMPOTENCY_KEY_REUSED409Reuse the exact original request to recover that operation, or use a new key only for a genuinely different operation.Do not retry a changed body with that key.
IDEMPOTENCY_IN_PROGRESS409Wait briefly, retry with the same key and unchanged request, then reconcile by reference if the result remains uncertain.Back off with jitter; preserve key/body.