PCI Vault Logo
Stripe Forwarding

This guide will help you set up a capture endpoint to accept card data forwarded by Stripe using their forwarding request API. Stripe Forwarding Token Vault

Overview

In this guide we will cover:

  1. Creating a rule to transform the data sent by Stripe
  2. Creating a capture endpoint
  3. Requesting access to Stripe Forwarding API
  4. Initiating a forwarding request

Step 1: Create a rule to transform the data sent by Stripe

The data forwarded to your vault from Stripe comes in the following format:

{
  "card": {
    "number": "4242424242424242",
    "exp_month": "12",
    "exp_year": "2023",
    "name": "John Doe",
    "cvc": "123"
  },
  "metadata": {
    "custom": "custom_value"
  }
}

The default format that our hosted forms capture the card data is in a flatter structure, so in order to keep the data consistent, we'll create a rule to transform the Stripe data into the same flat structure.

The capture endpoint we create in the next step will use this rule to transform the data right before it is stored. The data which gets stored in the vault will look like this after the rule is applied:

{
  "card_number": "4242424242424242",
  "expiry_month": "12",
  "expiry_year": "2023",
  "expiry_year_short": "23",
  "expiry": "12/23",
  "card_holder": "John Doe",
  "cvv": "123",
  "custom": "custom_value"
}

We'll use the Add Rule API to create a new rule.

Give the new rule a meaningful name in the id query parameter, enter stripe-forwarding-transform. In the body of the request we can create our list of operations:

{
  "operations": [
    {
        "name": "template",
        "input_field": "*",
        "output_field": "*",
        "order_position": 1,
        "arguments": {
            "template": "{\"card_number\": \"{{card.number}}\", \"expiry_month\": \"{{card.exp_month}}\", \"expiry_year\": \"{{card.exp_year}}\", \"card_holder\": \"{{card.name}}\", \"cvv\": \"{{card.cvc}}\", \"custom\": \"{{metadata.custom}}\"}"
        }
    },
    {
        "name": "substr",
        "input_field": "expiry_year",
        "output_field": "expiry_year_short",
        "order_position": 2,
        "arguments": {
            "start": -2,
            "end": 0
        }
    },
    {
        "name": "format",
        "input_field": "expiry_year",
        "output_field": "expiry",
        "order_position": 3,
        "arguments": {
            "format_string": "%v/%v",
            "keys": ["expiry_month", "expiry_year_short"]
        }
    }
  ]
}

The first operation is the template operation which flattens out the structure and renames some of the fields. Having the output_field set to * means that the output of the operation will replace the whole working object instead of storing it in a new field.

The second operation is the substr, this one takes the last two characters of the expiry_year and stores them in a new field expiry_year_short. It transforms 2025 to 25.

The last operation is the format, this one takes the newly constructed expiry_short_year from the previous operation and makes a formatted string e.g. 06/25, then outputs the value in a new field called expiry.

Submit the request to create the rule, we'll use it in the next step.

Step 2: Create a capture endpoint

Create an endpoint for capturing data using the POST /capture endpoint.

For more documentation on capture endpoints, check this documentation.

Use your key and passphrase parameters as normal. For the ttl parameter you should use a value of 0 or P0T0 in order to create an endpoint that never expires.

Lastly for the rules query parameter enter the id of the rule created in the previous step i.e. stripe-forwarding-transform

Submit the request and store the response somewhere safe, we'll need it later.

Step 3: Request access to Stripe Forwarding API

The Stripe Forwarding API is not enabled on your Stripe account by default, so it is necessary to request for it to be enabled. Create Stripe Support Ticket

Set your newly created endpoint url in the support ticket e.g https://api.pcivault.io/v1/capture/<endpoint_id> and also attach the PCI Vault Attestation of Compliance document which can be obtained through the GET /certificate request

Step 4: Initiate a forwarding request

Once Stripe has enabled the Forwarding API, you'll need to enable the X-PCIVault-Capture-Secret header to be forwarded.

curl --location 'https://api.stripe.com/v1/forwarding/requests' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Bearer <STRIPE_API_KEY>' \
--data-urlencode 'payment_method=<STRIPE_PAYMENT_METHOD_ID>' \
--data-urlencode 'url=https://api.pcivault.io/v1/capture/<CAPTURE_ENDPOINT_ID>?reference=<REFERENCE>' \
--data-urlencode 'request[headers][0][name]=X-PCIVault-Capture-Secret' \
--data-urlencode 'request[headers][0][value]=<CAPTURE_ENDPOINT_SECRET>' \
--data-urlencode 'request[body]={"card": {"number": "", "exp_month": "", "exp_year": "", "cvc": "", "name": ""}, "metadata": {"custom": "custom_value"}}' \
--data-urlencode 'replacements[0]=card_number' \
--data-urlencode 'replacements[1]=card_expiry' \
--data-urlencode 'replacements[2]=card_cvc' \
--data-urlencode 'replacements[3]=cardholder_name'

The above request tells Stripe to forward the specific payment method STRIPE_PAYMENT_METHOD_ID to the PCI Vault URL https://api.pcivault.io/v1/capture/<CAPTURE_ENDPOINT_ID>?reference=<REFERENCE>. Stripe will forward the data from their vault to our capture endpoint and return the response in a synchronous manner, returning the response from the capture endpoint.

Typically you would set up Stripe webhooks for payment_method.updated and payment_method.automatically_updated events, following the Stripe documentation. Whenever one of these events occur, you would initiate a forwarding request as in the example above, updating the card in your vault and keeping the data in sync.