# Payment Intent API

The *Payment Intent* API enables users to purchase cryptocurrencies using fiat currencies (e.g., buying BTC with EUR). Supported payment methods include credit card, bank transfer, Apple Pay, and Google Pay among others.

Once the payment is completed, the purchased crypto is sent to the wallet specified during order registration.

The API also supports KYC verification for new users if required.

### Create a new Payment Intent

This method allow to register a new payment intent.

A *Payment Intent* records a user's intent to purchase a specified amount of crypto and pay for it using fiat. Either the crypto amount or the fiat amount is defined during the creation of the *Payment Intent*.

For example, if a user wants to buy €1000 worth of BTC, the system will automatically calculate the corresponding BTC amount. Similarly, if the user wants to purchase 0.01 BTC, the system will determine the required fiat amount to complete the purchase.

Therefore, it is not necessary to provide both values. If both the crypto and fiat amounts are sent via the API, the system will prioritize the fiat amount and recalculate the crypto amount accordingly.

The fiat or crypto amounts calculated by the system can be retrieved through the payment instructions API call. This allows users to review and confirm the final amounts before proceeding with the payment.

When specifying a cryptocurrency, it is also important to specify the network to which the crypto should be sent. In the [Networks page](/ahoracrypto/api/networks.md), you can find a list of all supported networks.

{% hint style="info" %}
It is important to use the network symbol shown in the [Networks page](/ahoracrypto/api/networks.md) as the value for the `network` field.
{% endhint %}

If the user is required to complete the KYC process before purchasing crypto, this API call will return a URL where they can complete the verification. Additionally, a callback URL can be specified so that, once the KYC process is successfully completed, the user is redirected back to continue the purchase process.

{% hint style="info" %}
It is important to note that the IP address is part of the information sent when calling the API, and it must be the user's actual IP. Payment gateways require this data to verify the authenticity of the transaction.

Additionally, any data provided — such as the country — must be accurate and not inferred from other data points. If the actual value is unknown, it should be omitted.
{% endhint %}

#### IPN Url and Payment Intent Status

Optionally, we can specify an IPN URL to receive asynchronous notifications whenever the payment status changes—for example, when a user pays for an order or when the cryptocurrencies are sent to the user.

The IPN Url will be called via GET with 2 parameters:

* **paymentIntentId**: The ID of the payment intent
* **paymentIntentStatus**: The status of the payment intent (see the [payment status section](#get-payment-status) to see all possible values)

#### Return Value

The API call will return three values:

1. A *Payment Intent ID* to reference in subsequent API calls.
2. A *status* (see the [payment status section](#get-payment-status) to see all possible values). However, we can only retrieve payment instructions if the status is `4` (Ready to Pay)
3. A *KYC URL* (if required) where the user can complete the verification process.

To call the API, it is essential to include the `x-api-key` header.

Additionally, the `storeId` value, which is unique per client, must be specified for the API request to function correctly.

Both values are provided by *AhoraCrypto*.

## POST /payment/intent

>

```json
{"openapi":"3.0.0","info":{"title":"ahoracrypto-middleware","version":"0.0.1"},"servers":[{"url":"https://api.ahoracrypto.com"}],"security":[{"jwt":[]}],"paths":{"/payment/intent":{"post":{"tags":["PaymentController"],"responses":{"200":{"description":"Create payment intent","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Payment intent identifier"},"status":{"type":"integer","description":"Payment intent status"},"kycUrl":{"type":"string","description":"URL for KYC verification process"}},"required":["id","status"]}}}},"400":{"description":"Bad request - Missing required fields or invalid values"},"401":{"description":"Unauthorized - Missing or invalid API key"},"500":{"description":"Internal Server Error"}},"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"API key for authentication"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentIntentRequest"}}}},"operationId":"PaymentController.createPaymentIntent"}}},"components":{"schemas":{"PaymentIntentRequest":{"title":"PaymentIntentRequest","type":"object","properties":{"email":{"type":"string","description":"User email address"},"fiatCurrency":{"type":"string","description":"Fiat currency code (e.g., USD, EUR)"},"cryptoSymbol":{"type":"string","description":"Cryptocurrency symbol (e.g., USDT, BTC)"},"ipAddress":{"type":"string","description":"User IP address"},"walletAddress":{"type":"string","description":"Cryptocurrency wallet address"},"network":{"type":"string","description":"Blockchain network for the transaction"},"storeId":{"type":"string","description":"Unique identifier assigned by the API provider. Contact support to get your store ID."},"country":{"type":"string","description":"ISO country code (2 characters, e.g., ES for Spain, US for United States, ...)"},"phonePrefix":{"type":"string","description":"Country calling code (e.g., +1, +44)"},"phoneNumber":{"type":"string","description":"User phone number without country code"},"cryptoAmount":{"type":"number","description":"Amount in cryptocurrency to be received. If not specified, the fiat amount will be used to calculate the crypto amount."},"fiatAmount":{"type":"number","description":"Amount in fiat currency to be paid. If not specified, the crypto amount will be used to calculate the necessary fiat amount to be paid."},"kycCallbackUrl":{"type":"string","description":"URL to redirect the user after KYC verification is done in case the user has to pass the KYC verification"},"paymentCallbackUrl":{"type":"string","description":"URL to redirect the user after payment has been completed. Note that it does not mean that the payment has been successful, it means that the payment process has been completed. You should check the payment status via the GET /payment/intent/{id}/status endpoint."},"cancellationCallbackUrl":{"type":"string","description":"URL to redirect the user if they cancel the payment process"},"ipnUrl":{"type":"string","description":"URL where payment status notifications (IPN) will be sent. Payment status can be also retrieved via the GET /payment/intent/{id}/status endpoint."},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"documentType":{"type":"number","description":"Type of identification document"},"documentNumber":{"type":"string","description":"Identification document number"},"birthDate":{"type":"string","description":"User birth date in YYYY-MM-DD format"},"documentIssuedCountry":{"type":"string","description":"ISO country code of document issuance (2 characters, e.g., ES for Spain, US for United States, ...)"},"nationality":{"type":"string","description":"ISO country code for nationality (2 characters, e.g., ES for Spain, US for United States, ...)"},"kycVideoUrl":{"type":"string","description":"URL of KYC verification video"},"documentFrontUrl":{"type":"string","description":"URL of identification document front image"},"documentBackUrl":{"type":"string","description":"URL of identification document back image"}},"required":["email","fiatCurrency","cryptoSymbol","ipAddress","walletAddress","network","storeId"],"additionalProperties":false}}}}
```

### Get Payment Instructions

Once the *Payment Intent* has been registered and the payment is ready (i.e. because the payment status was `4` *Ready for Payment*), we can get the payment instructions. Note that we can't call this endpoint while payment status is not ready (e.g. if the user is pending for a KYC validation). We can check the status of a payment intent by calling the [Payment Intent Status endpoint](#get-payment-status) at any time.

To call this API, it is essential to include the `x-api-key` header.

We can retrieve the payment instructions by calling the following method:

## GET /payment/intent/{id}/instructions

>

```json
{"openapi":"3.0.0","info":{"title":"ahoracrypto-middleware","version":"0.0.1"},"servers":[{"url":"https://api.ahoracrypto.com"}],"paths":{"/payment/intent/{id}/instructions":{"get":{"tags":["PaymentController"],"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"API key for authentication"},{"name":"id","in":"path","schema":{"type":"string"},"required":true}],"responses":{"200":{"description":"Get payment instructions","content":{"application/json":{"schema":{"type":"object","properties":{"iban":{"type":"string","description":"International Bank Account Number"},"bic":{"type":"string","description":"Bank Identifier Code (SWIFT)"},"accountHolder":{"type":"string","description":"Name of the bank account holder"},"bankCountry":{"type":"string","description":"Country where the bank account is located (e.g. ES for Spain, US for United States, ...)"},"reference":{"type":"string","description":"Payment reference number the user has to indicate in the bank transfer"},"fiatAmount":{"type":"number","format":"double","description":"Amount to be transferred"},"fiatCurrency":{"type":"string","description":"Fiat currency code (e.g. EUR, USD, ...)"},"cryptoAmount":{"type":"number","format":"double","description":"Amount of crypto to be received"},"cryptoCurrency":{"type":"string","description":"Cryptocurrency symbol (e.g. USDT, BTC, ...)"},"walletAddress":{"type":"string","description":"Cryptocurrency wallet address to receive the crypto"},"network":{"type":"string","description":"Blockchain network for the transaction"},"creditCardPaymentUrl":{"type":"string","format":"uri","description":"URL to redirect the user for credit/debit card payment"},"choosePaymentMethodsUrl":{"type":"string","format":"uri","description":"URL to redirect the user for selecting a preferred payment method (e.g., credit card, Apple Pay, or Google Pay)"}},"required":["iban","bic","accountHolder","bankCountry","reference","amount"]}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden - KYC Required"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}},"operationId":"PaymentController.getPaymentInstructions"}}}}
```

### Get Payment Intent

This method allows you to retrieve information about an existing Payment Intent using its associated `orderNumber`.

Once a Payment Intent has been created for an order, you can check its status at any time using this endpoint. This is useful to determine whether the payment is ready, if additional steps such as KYC verification are required, or simply to obtain the ID of the Payment Intent linked to the order.

The response includes:

* The `paymentIntentId` associated with the order.
* The current `status` of the Payment Intent.
* If KYC is required, the `kycUrl` the user must visit to complete the verification process.

To call this API, it is essential to include the `x-api-key` header.

You can retrieve the Payment Intent information by calling the following method:

## GET /payment/intent/order/{orderNumber}

>

```json
{"openapi":"3.0.0","info":{"title":"ahoracrypto-middleware","version":"0.0.1"},"servers":[{"url":"https://api.ahoracrypto.com"}],"paths":{"/payment/intent/order/{orderNumber}":{"get":{"tags":["PaymentController"],"responses":{"200":{"description":"Get payment intent by order number","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Payment intent identifier"},"status":{"type":"integer","description":"Payment intent status"},"kycUrl":{"type":"string","nullable":true,"description":"URL for KYC verification process"}},"required":["id","status"]}}}},"401":{"description":"Unauthorized - Missing or invalid API key"},"404":{"description":"Payment intent not found"},"500":{"description":"Internal Server Error"}},"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"API key for authentication"},{"name":"orderNumber","in":"path","schema":{"type":"string"},"required":true}],"operationId":"PaymentController.getPaymentIntentByOrderNumber"}}}}
```

### Get Payment Status

At any time, we can check the status of a payment using this call.

Posible values are:

* `1` Initial state when payment intent is created but not yet processed
* `2` Waiting for user to complete KYC (Know Your Customer) verification. User can't pay and order can't be processed until the user has passed the KYC
* `3` Pending to pass a manual KYC verification. User has upload its documents to KYC center, but still need to be verified manually by AhoraCrypto. User can't pay and order can't be processed until the user has passed the KYC
* `4` Ready to pay, as all previous requirements (including KYC verification) have been fulfilled.
* `5` Payment has been received but order is still pending to be processed
* `6` Order has been processed successfully
* `10` Payment intent has timed out and is no longer valid
* `12` Payment was made but has been refunded to the user
* `14` Payment intent was cancelled before completion.
* `100` Payment was declined by the payment gateway. The order is still able to be paid in this status.
* `10000` General failure in payment / order processing
* `10001` User failed to pass KYC verification requirements
* `10002` The user belongs to a country that AhoraCrypto does not operated in.

It also returns an order number associated with the given payment intent ID, if it exists. Orders are created once the user has passed KYC validation and is able to pay for the order.

To call the API, it is essential to include the `x-api-key` header.

We can retrieve the payment instructions by calling the following method:

{% openapi src="/files/LKOZ5OMKN2kKD9Qo6TbK" path="/payment/intent/{id}/status" method="get" %}
[openapi.json](https://3932413945-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUgVueR2dIs5n8OaZ8mFw%2Fuploads%2FpLzrBLh4q9INjNCYvnj5%2Fopenapi.json?alt=media\&token=a19a4c2c-953f-473e-888f-b08ce9e2455f)
{% endopenapi %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ahoracrypto.gitbook.io/ahoracrypto/api/payment-intent.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
