Skip to main content

Process Card Payments

Storing your customers' cards with Basis Theory platform grants you the ability to seamlessly shift between payment processors, giving you competitive advantages including payment flexibility, reliability, cost savings, increased acceptance rates, and future-proofing your business against processor downtime or shutdown.

This guide will explore how to forward stored cardholder data to any third-party API endpoint, with minimal configuration requirements. By following the steps presented below, you are substantially de-scoping your servers and database from PCI DSS compliance. If you want to learn more about how we can help you meet up to 95% of the PCI requirements or if you need help filling out your SAQ, reach out to our team!

Charge Stored Cards

If you are not yet storing your customers' cards with Basis Theory, here are a few guides you can explore:

Getting Started

To get started, you will need a Basis Theory account and a Tenant.

Creating a Private Application

Next, you will need a Private Application using our PCI-compliant template Use PCI Tokens. Click here to create one.

This will create an application with the following Access Controls:

  • Permissions: token:use
  • Containers: /pci/
  • Transform: reveal
Save the API Key from the created Private Application as it will be used in the next steps of this guide.

Send the Data

We will use Basis Theory Ephemeral Proxy, a tool that transparently performs detokenization, to share the sensitive cardholder data to the Payments Processor or Acquirer API. To do this, we will formulate our HTTPS request as if we were directly connecting to the target endpoint, with the following variations:

  1. Use the previously-created Private Application Key as the value of the BT-API-KEY header;
  2. Specify the target API endpoint as the value for the BT-PROXY-URL header;
  3. Pass any additional headers you need the target API to receive, for example Authorization, X-API-KEY, etc.;
  4. Replace the plaintext sensitive cardholder data in the expected payload contents with detokenization expressions that contains token identifiers.

For example, given you have a previously stored card token with the following identifier:

"id": "d2cbc1b4-5c3a-45a3-9ee2-392a1c475ab4",
"type": "card",
"tenant_id": "15f48eb5-8b52-4cdd-a396-608f7cf001d0",
"data": {
"number": "XXXXXXXXXXXX4242",
"expiration_month": 12,
"expiration_year": 2025
"created_by": "4a6ae2a6-79f8-4640-968f-88db913743df",
"created_at": "2023-04-17T12:54:44.8320458+00:00",
"mask": {
"number": "{{ data.number | reveal_last: 4 }}",
"expiration_month": "{{ data.expiration_month }}",
"expiration_year": "{{ data.expiration_year }}"
"privacy": {
"classification": "pci",
"impact_level": "high",
"restriction_policy": "mask"
"search_indexes": [],
"containers": [

Here are a few integration examples of how to send the detokenized card information to third party APIs.

Create a Payment Method
curl '' \
-X 'POST' \
-H 'BT-API-KEY: test_1234567890' \
-H 'Authorization: Bearer sk_test_51KMGNYGuvJF9SIWEW0y4rKcaQwLVLck2rGB8UEPHzSp1utx7gXKAfZ3DVgjMfAuvBIT42pQhg0sIx2PepEJkXv9g00yIrUwhI4' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'type=card' \
--data-urlencode 'card[number]={{ d2cbc1b4-5c3a-45a3-9ee2-392a1c475ab4 | json: "$.number" }}' \
--data-urlencode 'card[exp_month]={{ d2cbc1b4-5c3a-45a3-9ee2-392a1c475ab4 | json: "$.expiration_month" }}' \
--data-urlencode 'card[exp_year]={{ d2cbc1b4-5c3a-45a3-9ee2-392a1c475ab4 | json: "$.expiration_year" }}' \
--data-urlencode 'card[cvc]={{ d2cbc1b4-5c3a-45a3-9ee2-392a1c475ab4 | json: "$.cvc" }}'

Stripe Payment Method Docs

Key Considerations

You are not restricted to the Payment Processors listed above. As long as your partner can accept cards through an API endpoint, you can invoke it using the Ephemeral Proxy.

If you find that the HTTPS response from your processor contains cardholder data, you can use a Pre-Configured Proxy to redact or tokenize the sensitive data points using a Response Transform.

It's important to note that for some acquirers, inbound connections are only accepted from whitelisted IP addresses provided by the client. To help with this, here you can find a compiled list of our IP addresses that you can send to your acquirer. In cases of more restrictive integrations, Basis Theory can provide dedicated IPs upon request. If you're interested in this option, please don't hesitate to contact us.

During testing phase, make sure to create tokens using test cards documented by your payment processor, following the desired test scenario. Passing incorrect cards to test/sandbox endpoints may lead to hard-to-debug rejected transactions.


By using our Ephemeral Proxy, you can confidently transmit cardholder data to Payment Processors via API requests without ever touching the card details yourself. This approach not only improves security and reduces compliance risks but also provides the flexibility to establish your own relationships with Payment Processors and the latest payment technologies.

Learn More