---
updatedAt: 2025-02-20T00:51:38.000Z
agentTools:
  projectIndex: https://revio.readme.io/llms.txt
---

# Retrieve an object by ID.

# OpenAPI definition

```json
{
  "openapi": "3.1.0",
  "info": {
    "title": "Public REST API",
    "version": "v1",
    "description": "All the endpoints below have a prefix of `https://gate.reviopay.com/api/v1/` (e.g. `POST https://gate.reviopay.com/api/v1/purchases/`).\n\nYou will need your API key that you can obtain in the Developers section in your account. Please use this key as a bearer token in the Authorization header included in every request: `Authorization: Bearer <secret key>`.\n\nBefore starting the development, we recommend checking out the list of ready-to-go connectors to the popular platforms we’ve already built for you. It might save you some precious time if you use one of these to develop your project.\n\nPlugins: [WooCommerce](https://gate.reviopay.com/apis/plugins/WooCommerce%20v3.5+), [OpenCart](https://gate.reviopay.com/apis/plugins/OpenCart%20v3.0+), [Magento](https://gate.reviopay.com/apis/plugins/Magento%20v2.0+), [PrestaShop](https://gate.reviopay.com/apis/plugins/PrestaShop%20v1.7+)\n\n\n\n\n\nSDKs: [iOS](https://gate.reviopay.com/apis/sdks/iOS), [Android](https://gate.reviopay.com/apis/sdks/Android)\n***\n\n# Online Purchases\n\n## Prebuilt payment flow — Redirect\n\nRedirect integration allows running payments using the prebuilt payment flow.\n\nTo accept payments in your application or website via redirect, use `POST /purchases/` request to create the `Purchase` and receive the `checkout_url`. Redirect the customer to the `checkout_url` to enter their card details for processing. After the payment is processed, the system will redirect the customer back to your website (take note of `success_redirect`, `failure_redirect`).\n\n*You have three options to check payment status:*\n\n1. Use `success_callback` parameter of the `Purchase` object.\n\n2. Use `GET /purchases/<purchase_id>/` request.\n\n3. Set up a Webhook using the Developers section of your account or use Webhook API to listen to `purchase.paid`, or `purchase.payment_failure` event on your server.\n\nSetting the `skip_capture` flag to `true` allows you to separate the authentication and payment execution steps, allowing you to reserve funds on the customer's card account for some time.\n\nThis flag can also enable preauthorization capability, allowing you to save the card without a financial transaction, if possible.\n\nIf the customer agrees to store his card for future purchases, there will be an option to pay with a single click next time. To enable this, create a `Client` object for each of your clients and provide `client_id` parameter value in your Purchase creation requests.\n\nTo create a Purchase or a BillingTemplate, you must specify the `Brand ID` and `API key`. You can find both in the Developers section of your account.\n\n\n\n## Custom payment flow — Direct Post\n\nDirect post integration allows running payments through the custom payment flow.\n\nTo accept payments in your application or website, use `POST /purchases/` request to create a `Purchase`.\n\nTo capture customers card details use an HTML `<form>` hosted on your website with `method=\"POST\"` and `action` pointing to the `direct_post_url` of the transaction.\n\nYou will also need to fill the form with `<input>`'s for the fields with card details. As a result, when a customer submits their card details, it will be posted straight to our system, allowing you to customize the checkout as you wish. At the same time, your PCI DSS requirement is only raised to Self-Assessment Questionnaire (SAQ A-EP), as your system doesn't receive or process card data.\n\nFor more details, see the documentation on Purchase's `direct_post_url` field.\n\n### Tokenization & recurring payments\n\nYou can store card tokens and charge the respective cards without user interaction if the payment channel supports tokenization.\n\nWhen you pass `remember_card=on` to `direct_post_url`, the respective `Purchase`'s ID will serve as a card token. This initial `Purchase` will have the `is_recurring_token` field set to `true`.\n\nTo charge the tokenized card once again, create a new Purchase and then call the `POST /purchases/{new_purchase_id}/charge/`. In the request body, provide `\"recurring_token\": \"initial_purchase_id\"`. When the request succeeds (response code `200`), the new Purchase will become paid. The token will be persisted in the Purchase's recurring_token field.\n\nUse `\"recurring_token\": \"initial_purchase_id\"` in all the upcoming `POST /purchases/{new_purchase_id}/charge/` requests.\n\nIf you wish to delete the recurring token stored for the initial `Purchase`, use the `POST /purchases/{initial_purhcase_id}/delete_recurring_token/` request. Its `is_recurring_token` will reset to `false`.\n\n## Custom payment flow — Server-to-Server\n\nServer-to-Server (\"S2S\") integration allows running payments on the server level without direct interaction between the client’s browser or application and API.\n\nYou can build an integration that prevents payers from accessing platform resources directly. In this flow, 3D Secure implementation allows API clients to:\n\nCheck 3D Secure enrolment, and if the card is enrolled, receive ACS URL together with all the necessary params for redirection to ACS (PaReq, MD);\nRedirect the payer to the ACS system of their issuer bank;\nReceive the payer back and execute the authorization with a separate request.\n\nIf the card is not enrolled in 3D Secure, authorization will execute synchronously.\n\nTo accept payments in your application or website via S2S:\n\n1.  Ensure the Purchase is created as described in Custom payment flow — Direct Post. As per the Purchase's direct_post_url field description, you will need to ensure all the necessary criteria are met, including success_redirect/failure_redirect fields defined for Purchase and set to arbitrary valid URLs (they will not receive any redirects in the S2S scenario);\n2.  Implement the following request in your server code, appending \"?s2s=true\" to direct_post_url to form the resulting endpoint (you can obtain the S2S token value from your account manager):\n\n        POST {direct_post_url}?s2s=true\n\n    Specify the following headers:\n\n        Content-Type: application/json\n        Authorization: Bearer {S2S token}\n\n    In the request body, provide the following data in JSON (you can omit some of the fields, then system will use default values; We recommend providing correct values from the user’s browser as it can affect 3D Secure success rate):\n\n        {\n          \"cardholder_name\": \"John Doe\",\n          \"card_number\": \"4444333322221111\",\n          \"expires\": \"01/23\",\n          \"cvc\": \"123\",\n          \"remember_card\": \"on\",\n          \"remote_ip\": \"8.8.8.8\",\n          \"user_agent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36\",\n          \"accept_header\": \"text/html\",\n          \"language\": \"en-US\",\n          \"java_enabled\": false,\n          \"javascript_enabled\": true,\n          \"color_depth\": 24,\n          \"utc_offset\": 0,\n          \"screen_width\": 1920,\n          \"screen_height\": 1080\n        }\n\n    |Field name&nbsp;|Required&nbsp;|Validation criteria/remarks&nbsp;|Default value|\n    |--- |--- |---|--- |\n    |cardholder_name|Y|Latin letters only (space and apostrophe ('), dot (.), dash (-) symbols are also allowed), max 30 characters||\n    |card_number|Y|text, digits only, no whitespace, max 19 characters||\n    |expires|Y|text in 'MM/YY' format, digits and a slash only (/^\\\\d{2}\\\\/\\\\d{2}$/), max 5 characters||\n    |cvc|Y|numeric string of 3 or 4 digits||\n    |remember_card|N|literal value \"on\" to save card, any other string otherwise||\n    |remote_ip|Y|external IP of payer’s browser in IPv4 or IPv6 format||\n    |user_agent|N|User-Agent as sent by the payer’s browser, max 2048 charge|Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/ 537.36 (KHTML, like Gecko) Chrome/ 88.0.4324.96 Safari/ 537.36|\n    |accept_header|N|Same as above, max 2048 characters|text/html|\n    |language|N|Same as above, max 8 characters|en-US|\n    |java_enabled|N|boolean|false|\n    |javascript_enabled|N|boolean|true|\n    |color_depth|N|integer in 0-255 range|24|\n    |utc_offset|N|integer in -32,768 to 32,767 range|0|\n    |screen_width|N|integer in uint64 range|1920|\n    |screen_height|N|integer in uint64 range|1080|\n\n3.  If the card is not enrolled in 3S Secure, then a response will contain the field \"status\" with one of the following values:\n\"executed\" in case of a successful payment authorization;\n\"authorized\" in case fund reservation using Purchase.skip_capture was requested;\n\"error\" in case of an authorization error.\n\n    Example:\n\n        {\"status\": \"executed\"}\n\n    You will receive \"executed\" or \"authorized\" statuses with a response status code 200 and \"error\" status - with a status code of 400.\n\n    In all of those cases, it is necessary to set up webhooks for purchase events (`purchase.paid, purchase.payment_failure` at least) to receive further information about the status of the financial transaction.\n\n4.  If the card is enrolled in 3D Secure, the response will have a status code of 200, the status will be 3DS_required, and the response will contain additional fields:\n\n        {\n          \"status\": \"3DS_required\",\n          \"Method\": \"(POST|GET)\",\n          \"PaReq\": \"...\",\n          \"MD\": \"... (can arrive empty)\",\n          \"URL\": \"http://url.of.acs.bank/\",\n          \"callback_url\": \"https://...\"\n        }\n\n    It’s necessary to ensure your client’s browser makes a request with the method specified in `Method` (GET or POST only) to the ACS of issuer bank returned in \"URL\", including the values of `MD` and `PaReq` as received (use query params in case of GET and request body params in case of POST). Be aware that MD might arrive empty – in that case, you can send it further as an empty string.\n\n    In addition to those, you also **need to include the `TermUrl` parameter** in the client’s browser request, pointing to the URL in your system where the customer’s navigation will be expected. Once the payer approves the transaction, he will be redirected using the POST method to that URL with `MD` and `PaRes` params in the request body.\n\n5.  Once the client is back to `TermUrl` in your system and you have received the `MD` and `PaRes`, it’s needed to transmit them to the platform to complete the authorization. Send the following request from your server code (no auth headers required):\n\n        POST {callback_url from step 4.}\n\n        Content-Type: application/x-www-form-urlencoded\n        MD={MD received, if any}&PaRes={PaRes received}\n\n    The response will contain the authorization status in JSON format and will be identical to the format described in the previous section.\n\n## Testing Integration\n\nIt’s possible to test-drive all checkouts using a test Purchase.\n\nFor a successful payment, you can use the following card numbers:\n\n*   4444 3333 2222 1111 - non-3D Secure card\n*   5555 5555 5555 4444 - 3D Secure card\n\nFor both cards, please use:\n\n*   any cardholder name\n*   any expiry larger or equal to the current month/year\n*   CVC = 123\n\nFor a failed payment, please change the CVC or expiration date.\n\nWhen using a 3D Secure enrolled card in S2S checkout,  an incorrect CVC will trigger an authorization failure on the S2S callback step (after the customer returns from test ACS). Using a wrong expiry date emulates data validation failure and results in immediate error before that step.\n\n\n***\n\n# Billing\n\n## Invoicing\n\nTo send one-off invoices, use `POST /billing/` request. It's similar to `POST /purchases/` except that customers are an array, allowing you to bulk-issue invoices to several customers at once.\n\nTo send invoices using a template, use a separate `POST /billing_templates/` request (without `clients`!). Then, for each of your clients, use `POST /billing_templates/{billing_template_id}/send_invoice/`.\n\nIf the customer agrees to store his card for future purchases, then the next time the option to pay with a single click will appear if the payment channel supports tokenization.\n\n***\n\n## Subscriptions\n\nSubscriptions allow you to automate recurring purchases. You can create a subscription using the same request `POST /billing_templates/` as for invoices. To create a subscription billing template, specify `is_subscription: true` and `subscription_*` fields in `POST /billing_templates/` request body. Then, add subscribers using the `POST /billing_templates/<billing_template_id>/add_subscriber/` request.\n\nIf the payment channel supports tokenization and the customer agreed to store his datafor future purchases, payments will be processed automatically, while the customer will get a receipt for each purchase. Note that whenever a subscription payment fails, your customer will automatically receive an invoice he can pay (and store a new card for upcoming payments in the process). Your system will also receive the `purchase.subscription_charge_failure` webhook event, if configured.\n\nBy default, the system generates invoices and processes subscription payments at the beginning of the billing cycle.\n\nIf you want to send an invoice or charge a customer at the end of the billing cycle, just set `subscription_charge_period_end` to `true` in `POST /billing_templates/` request.\n\nThe API also provides you with an option to give a trial to your customers before enabling paid subscription period. To do that just set `subscription_trial_periods` in `POST /billing_templates/` request.\n\n***\n\n# Callbacks\n\nTwo methods for defining asynchronous callbacks are supported - `Purchase` success callbacks and webhooks.\n\n## Purchase success callbacks\n\n`Purchase` success callbacks are defined by providing a target URL in the `success_callback` field on `Purchase` creation (see [POST /purchases/](#/Purchases/purchases_create)). The system will generate a callback when:\n* a `Purchase` with `skip_capture=false` is successfully paid;\n* a `Purchase` with `skip_capture=true` is successfully captured (see [POST /purchases/{id}/capture/](#/Purchases/purchases_capture));\n* a `Purchase` is successfully paid using a recurring token (see [POST /purchases/{id}/charge/](#/Purchases/purchases_charge));\n\nThese callbacks pass a JSON-encoded `Purchase` as their payload. The payload represents a snapshot of the state of the `Purchase` when the event was created. The payload will include an `event_type` field to indicate which specific event (see [Event schema](#model-Event)) triggered the callback.\n\nThe payload is signed using a company-wide key pair. You can obtain the public key with `GET /public_key/`. See the `Authentication` section below for more details.\n\n## Webhooks\n\nFor creating and modifying webhooks, see the Webhook [CRUD API specification](#operations-tag-Webhooks).\n\n`Webhook` callback payloads are signed using a dedicated key pair. You can obtain the public key from `Webhook.public_key`. See the [Authentication](#callback-auth) section below for more details.\n\n## Delivery protocol\n\nWhen a callback is not successfully delivered (received by the target server and responded to with a 200 series HTTP response code), the system will make up to 8 additional attempts at exponentially increasing intervals between attempts. No further delivery attempts will be made if the callback is not successfully delivered 36 hours after triggering.\n\nPlease note that due to the asynchronous nature of network requests, it is possible for a callback delivery confirmation (HTTP response with a 200 series status code) to not properly arrive from the callback's target server. Therefore it is possible in case of severe network faults for the target server to receive a callback, respond to it with a 200 series HTTP status code and then receive the same callback after an interval.\n\nCallback deliveries are guaranteed to be sequential to events triggered on their source objects. For example, when registering webhooks for both the `purchase.created` and `purchase.paid` events, there will be no `purchase.paid` callbacks for this `Purchase` until all `purchase.created` callbacks for this `Purchase` are successfully delivered.\n\n## <b id=\"callback-auth\">Authentication</b>\n\nPayloads are signed using asymmetric A.K.A. public-key cryptography to guarantee the authenticity of delivered callbacks. Each callback delivery request includes an X-Signature header field. This field contains a base64-encoded RSA PKCS#1 v1.5 signature of the SHA256 digest of the request body buffer.\n\nYou can obtain the public key for `Webhook` authentication from `Webhook.public_key` of the corresponding `Webhook`.\n\nYou can obtain the public key for success callback authentication from [GET /public_key/](#operations-Public_Key-public_key).\n\nPlease note the provider is not responsible for any financial losses incurred due to not implementing payload signature verification.\n"
  },
  "servers": [
    {
      "url": "https://gate.reviopay.com/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/clients/{client_id}/recurring_tokens/{id}/": {
      "parameters": [
        {
          "$ref": "#/components/parameters/id"
        },
        {
          "$ref": "#/components/parameters/client_id"
        }
      ],
      "get": {
        "operationId": "client_recurring_tokens_read",
        "responses": {
          "200": {
            "$ref": "#/components/responses/ClientRecurringToken"
          },
          "404": {
            "$ref": "#/components/responses/404"
          }
        },
        "summary": "Retrieve an object by ID.",
        "tags": [
          "Clients"
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    },
    "parameters": {
      "id": {
        "name": "id",
        "required": true,
        "in": "path",
        "description": "Object ID (UUID)",
        "schema": {
          "$ref": "#/components/schemas/UUID"
        }
      },
      "client_id": {
        "name": "client_id",
        "required": true,
        "in": "path",
        "description": "Object ID (UUID)",
        "schema": {
          "$ref": "#/components/schemas/UUID"
        }
      }
    },
    "responses": {
      "404": {
        "description": "No such object"
      },
      "ClientRecurringToken": {
        "description": "OK",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ClientRecurringToken"
            }
          }
        }
      }
    },
    "schemas": {
      "BaseModel": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "readOnly": true,
            "description": "Object type identifier"
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "readOnly": true
          },
          "created_on": {
            "readOnly": true,
            "description": "Object creation time",
            "allOf": [
              {
                "$ref": "#/components/schemas/UnixTimestamp"
              }
            ]
          },
          "updated_on": {
            "readOnly": true,
            "description": "Object last modification time",
            "allOf": [
              {
                "$ref": "#/components/schemas/UnixTimestamp"
              }
            ]
          }
        }
      },
      "ClientRecurringToken": {
        "allOf": [
          {
            "$ref": "#/components/schemas/BaseModel"
          },
          {
            "description": "A record of one of `recurring_token`-s saved for a specific client. `id` of this object will be the same as the `recurring_token` saved.",
            "properties": {
              "payment_method": {
                "type": "string",
                "readOnly": true,
                "description": "Payment method used to create this token, e.g. `card`."
              },
              "description": {
                "type": "string",
                "readOnly": true,
                "description": "Description of this token, if available. For card payments, this field will contain the masked card number."
              }
            }
          }
        ]
      },
      "UnixTimestamp": {
        "type": "integer",
        "format": "Unix timestamp (seconds)",
        "example": 1619740800
      },
      "UUID": {
        "type": "string",
        "format": "uuidv4"
      }
    }
  },
  "x-readme": {
    "explorer-enabled": true,
    "proxy-enabled": true
  }
}
```