---
title: "Decrypting Card Payload: Shopify Payments App"
description: Our goal was to support an early adopter of the Shopify App program by leveraging an existing outsourced Node.js-powered cardholder data environment (CDE).
image: https://blog.basistheory.com/hubfs/Decrypt%20Shopify.webp
---

[Skip to content](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#main-content)

![Basis Theory logo](https://blog.basistheory.com/hs-fs/hubfs/BTLogo%20(1).png?width=365&height=122&name=BTLogo%20(1).png)

- [Use Cases](https://basistheory.com/)
  
  Show submenu for Use Cases 
  
    - [Creator Economy](https://basistheory.com/use-cases/creator-economy)
    - [Digital Health](https://basistheory.com/use-cases/health)
    - [E-Commerce](https://basistheory.com/use-cases/ecommerce)
    - [Fintech](https://basistheory.com/use-cases/fintech)
    - [Gaming](https://basistheory.com/use-cases/gaming)
    - [Subscription Merchants](https://basistheory.com/use-cases/subscriptions)
    - [Travel](https://basistheory.com/use-cases/travel)
    - [VSaaS](https://basistheory.com/use-cases/vsaas)
- Solutions
  
  Show submenu for Solutions 
  
    - [Agentic Commerce](https://basistheory.com/solution/agentic-commerce)
    - [Data Consolidation](https://basistheory.com/solution/data-consolidation)
    - [Monetize Payments](https://basistheory.com/solution/monetize-payments)
    - [Multi PSP](https://basistheory.com/solution/multi-psp)
    - [Payment Method Discovery](https://basistheory.com/solution/payment-method-discovery)
    - [Payment Vault](https://basistheory.com/solution/payment-vault)
- [Platform](https://basistheory.com/platform)
  
  Show submenu for Platform 
  
    - [Enrichments & Add-Ons](https://basistheory.com/add-ons)
    - [Partners](https://basistheory.com/partnerships)
    - [Why Basis Theory](https://basistheory.com/why-basis-theory)
- [Pricing](https://basistheory.com/pricing)
- Resources
  
  Show submenu for Resources 
  
    - [Blog](https://blog.basistheory.com)
    - [Case Studies](https://blog.basistheory.com/case-studies)
- [Docs](https://developers.basistheory.com/)

Open main navigation

Close main navigation

- [Use Cases](https://basistheory.com/)
  
  Show submenu for Use Cases 
  
    - [Creator Economy](https://basistheory.com/use-cases/creator-economy)
    - [Digital Health](https://basistheory.com/use-cases/health)
    - [E-Commerce](https://basistheory.com/use-cases/ecommerce)
    - [Fintech](https://basistheory.com/use-cases/fintech)
    - [Gaming](https://basistheory.com/use-cases/gaming)
    - [Subscription Merchants](https://basistheory.com/use-cases/subscriptions)
    - [Travel](https://basistheory.com/use-cases/travel)
    - [VSaaS](https://basistheory.com/use-cases/vsaas)
- Solutions
  
  Show submenu for Solutions 
  
    - [Agentic Commerce](https://basistheory.com/solution/agentic-commerce)
    - [Data Consolidation](https://basistheory.com/solution/data-consolidation)
    - [Monetize Payments](https://basistheory.com/solution/monetize-payments)
    - [Multi PSP](https://basistheory.com/solution/multi-psp)
    - [Payment Method Discovery](https://basistheory.com/solution/payment-method-discovery)
    - [Payment Vault](https://basistheory.com/solution/payment-vault)
- [Platform](https://basistheory.com/platform)
  
  Show submenu for Platform 
  
    - [Enrichments & Add-Ons](https://basistheory.com/add-ons)
    - [Partners](https://basistheory.com/partnerships)
    - [Why Basis Theory](https://basistheory.com/why-basis-theory)
- [Pricing](https://basistheory.com/pricing)
- Resources
  
  Show submenu for Resources 
  
    - [Blog](https://blog.basistheory.com)
    - [Case Studies](https://blog.basistheory.com/case-studies)
- [Docs](https://developers.basistheory.com/)
- [Get a demo](https://basistheory.com/contact)

[Login](https://portal.basistheory.com/)

[Get a demo](https://basistheory.com/contact)

 December 15, 2025

![Picture of Davi Aquino](https://blog.basistheory.com/hs-fs/hubfs/Davi-Square.jpg?width=50&name=Davi-Square.jpg) [Davi Aquino](https://blog.basistheory.com/author/davi-aquino) ·

[Engineering](https://blog.basistheory.com/tag/engineering) [Payments](https://blog.basistheory.com/tag/payments)

# Decrypting Card Payload for Shopify Payments

![](https://blog.basistheory.com/hubfs/Decrypt%20Shopify.webp)

## Table of Contents

- [The Problem](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#Problem)
- [The Solution](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#Solution)
- [Shopify Payment App (Video)](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#Video)

When this video was recorded, Shopify Payment App documentation was in its early stages and only depicted Ruby code samples. 

Our goal was to support an early adopter of the program by leveraging their existing outsourced Node.js-powered cardholder data environment (CDE).

Watch the video recap or read on for the full story:

 

[Return to Top](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#TOC)

## The Problem 

In the technical discovery call with a customer, they mentioned that they got into the Shopify Payments App program. This enables them to access the encrypted consumer's credit card, as long as they receive it in a PCI-compliant environment.

The way this works is: when a consumer enters their credit card information on the checkout page, Shopify will call the Payment App passing the payload, which contains encrypted card information. The App must respond with a 200 OK, and can asynchronously do the payment processing. When it is done, they may call Shopify to finalize the Payment, who will notify the user.

At first, `start_payment_session` feels like a webhook, and a job for what we call here at Basis Theory the Inbound Proxy, which is programmable. Without going into too many details about how this works, let’s just say you can run serverless functions to transform the incoming payload before it hits your servers.

The other interesting requirement is that, in order to confirm Shopify's identity, they make that request using mTLS, while employing their self-signed certificate. So our platform team configured a particular DNS record to accept it, by checking it against Shopify's self-signed CA certificates. 

Easy, right?

Now for the job to be done, we had another challenge: securely perform ECIES hybrid decryption in our Proxy to obtain the plaintext card information, tokenize it, and send the token ID to our customer servers, so they can later process the payment with any downstream acquirer that they prefer. 

The updated diagram looks roughly like this. 

![shopify-payment-app-diagram](https://blog.basistheory.com/hs-fs/hubfs/shopify-payment-app-diagram.png?width=695&height=522&name=shopify-payment-app-diagram.png)

Again, the customer completes the checkout in Shopify, that using mTLS will call the [Basis Theory Proxy](https://developers.basistheory.com/docs/concepts/proxies/) passing the encrypted cardholder data. The Proxy decrypts and tokenizes the credit card, and calls the Payment App sending the original payload, but replacing the card information with a token. The Payment App responds with a 200 OK which is forwarded back to Shopify.

Now the Payment App can connect to any acquirer of their preference for doing the actual payment processing. Once that is done, it will finalize the payment against Shopify, which will notify the customer.

[Return to Top](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#TOC)

## The Solution 

Shopify has an example of how to perform the decryption using Ruby. But our [Proxy](http://developers.basistheory.com/docs/concepts/what-is-the-proxy) transform functions only operate in Node.js environment today. 

My obvious first attempt was to look for a popular NPM package that was capable of decrypting the payload following Shopify's specifications, without too much boilerplate code. See, this code was going to be shared with our client and needed to be as short and easy to maintain as possible, so hopefully we could replicate the pattern for other customers, too.

Since no NPM package did what we needed, I started digging into ECIES Hybrid encryption and tried to replicate the code in Node.js. The steps looked very similar to Apple Pay and Google Pay token debundling, for which I wrote a decryption package in the near past. 

However, each company customizes its specifications, using different key lengths, elliptic curve, and other parameters. I can't personally tell if one or another is more or less secure, so I leave that to mathematicians.

It all comes down to 4 steps: 

1. Compute a shared secret between your private key and the client-given ephemeral public key, using Elliptic Curve Diffie-Hellman (ECDH.)
2. Derive a symmetric key pair - which is a MAC Key and an Encryption Key, from the shared secret, using the specified KDF - which is a key derivation function.
3. Use the MAC Key to verify the message signature or tag.
4. Use the Encryption key to decrypt the payload.

After many hours in Stack Overflow and countless prompts in Chat GPT and Bard, the POC code finally worked. I was successfully verifying the encrypted code payload and obtaining the plaintext card number, expiration, and CVC. 

So I did some code polishing, added key rotation support, and published a [Shopify JS package](https://github.com/Basis-Theory/shopify-js)under the company's open-source repositories. We may end up consolidating all encryption utilities in a single repository in the future, but for now, our customers and the community can make use of [this maintained package](https://github.com/Basis-Theory/shopify-js) in their Node.js environments.

[Return to Top](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#TOC)

### Resources Used in Our Research

- [https://cryptobook.nakov.com/asymmetric-key-ciphers/ecies-public-key-encryption](https://cryptobook.nakov.com/asymmetric-key-ciphers/ecies-public-key-encryption)
- [https://www.youtube.com/watch?v=NmM9HA2MQGI](https://www.youtube.com/watch?v=NmM9HA2MQGI)
- [https://developer.apple.com/documentation/passkit/apple\_pay/payment\_token\_format\_reference](https://developer.apple.com/documentation/passkit/apple_pay/payment_token_format_reference)
- [https://developers.google.com/pay/api/android/guides/resources/payment-data-cryptography](https://developers.google.com/pay/api/android/guides/resources/payment-data-cryptography)
- [https://shopify.dev/docs/apps/payments/implementation/process-a-payment/credit-card](https://shopify.dev/docs/apps/payments/implementation/process-a-payment/credit-card)

[Return to Top](https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app#TOC)

[![View an Interactive Demo   See how the Basis Theory platform secures payment data and significantly reduces PCI compliance burden from day 1.  ](https://no-cache.hubspot.com/cta/default/22332934/interactive-171495116167.png)](https://blog.basistheory.com/hs/cta/wi/redirect?encryptedPayload=AVxigLKBIQaMcY%2FJjSBvhltDeuwvjpRZULDKvUpxGjWnAeZ4drq1HpnPiXs2qiSUMTbLaqKGk2M3GQs5wtntez4oWw1%2BAeqf0NMoOb%2Fpstq%2BSVczK%2F4E7sY9irdiNGBcvmBb3YK5H1%2B5zdf%2F5NB88XmOOzJMZlcQxcL9Gg1uJWwR3SqL%2FAApCr9W0s4w2eCogpJDxLExTF0gGgIE8T2%2Fz9Hi5ImGDHc%3D&webInteractiveContentId=171495116167&portalId=22332934)

## Related posts

[![Monolithic payment systems](https://blog.basistheory.com/hubfs/monolithic-payments.webp)](https://blog.basistheory.com/monolithic-payments)

[Payments](https://blog.basistheory.com/tag/payments)

### [Are Monolithic Payments a Thing of the Past?](https://blog.basistheory.com/monolithic-payments)

![Picture of Basis Theory](https://blog.basistheory.com/hs-fs/hubfs/bt-favicon-new.png?width=50&name=bt-favicon-new.png) [Basis Theory](https://blog.basistheory.com/author/basis-theory-team) 

 April 19, 2024

[Read more](https://blog.basistheory.com/monolithic-payments)

[![The Visa Stop Payment Service from Visa allows consumers to prevent card-on-file transactions through the Visa network.](https://blog.basistheory.com/hubfs/Visa%20stop%20payment%20service.png)](https://blog.basistheory.com/visa-stop-payment-service)

[Payments](https://blog.basistheory.com/tag/payments)

### [What the Visa Stop Payment Service Does for Merchants](https://blog.basistheory.com/visa-stop-payment-service)

![Picture of Basis Theory](https://blog.basistheory.com/hs-fs/hubfs/bt-favicon-new.png?width=50&name=bt-favicon-new.png) [Basis Theory](https://blog.basistheory.com/author/basis-theory-team) 

 July 25, 2024

[Read more](https://blog.basistheory.com/visa-stop-payment-service)

[![The Payment Process](https://blog.basistheory.com/hubfs/How%20Does%20Payment%20Processes%20Work.png)](https://blog.basistheory.com/stages-of-payment-processing)

[Payments](https://blog.basistheory.com/tag/payments)

### [The Payment Process: Who's involved at what stage?](https://blog.basistheory.com/stages-of-payment-processing)

![Picture of Basis Theory](https://blog.basistheory.com/hs-fs/hubfs/bt-favicon-new.png?width=50&name=bt-favicon-new.png) [Basis Theory](https://blog.basistheory.com/author/basis-theory-team) 

 September 16, 2025

[Read more](https://blog.basistheory.com/stages-of-payment-processing)

## Stay Connected

### Receive the latest updates straight to your inbox

### Follow on Social

<https://www.linkedin.com/comm/mynetwork/discovery-see-all?usecase=PEOPLE_FOLLOWS&followMember=colinthomasluce>

[![BTLogo (1)](https://blog.basistheory.com/hs-fs/hubfs/BTLogo%20(1).png?width=138&height=46&name=BTLogo%20(1).png "BTLogo (1)")](https://basistheory.com)

- Use Cases 
    - [Creator Economy](https://basistheory.com/use-cases/creator-economy)
    - [Digital Health](https://basistheory.com/use-cases/health)
    - [E-Commerce](https://basistheory.com/use-cases/ecommerce)
    - [Fintech](https://basistheory.com/use-cases/fintech)
    - [Gaming](https://basistheory.com/use-cases/gaming)
    - [Remittance](https://basistheory.com/use-cases/remittance)
    - [Subscription Platforms](https://basistheory.com/use-cases/subscriptions)
    - [Online Travel Agencies](https://basistheory.com/use-cases/travel)
    - [Vertical SaaS](https://basistheory.com/use-cases/vsaas)
- Developers 
    - [Quickstart](https://developers.basistheory.com/getting-started)
    - [Elements](https://developers.basistheory.com/docs/sdks/web/javascript)
    - [Documentation](https://developers.basistheory.com/)
- Basis Theory 
    - [Pricing](https://basistheory.com/pricing)
    - [Add-Ons](https://basistheory.com/add-ons)
    - [ROI Calculator](https://go.basistheory.com/roi)
    - [Case Studies](https://blog.basistheory.com/case-studies)
    - [Blog](https://blog.basistheory.com)
    - [Contact](https://basistheory.com/contact)
- Other 
    - [Terms and Conditions](https://basistheory.com/resources/terms-of-service)
    - [Privacy Policy](https://basistheory.com/resources/privacy-policy)
    - [Cookie Policy](https://basistheory.com/resources/cookie-policy)
    - [Security](https://basistheory.com/security)
    - [System Status](https://status.basistheory.com/)
- Compare 
    - [Basis Theory Vs. Evervault](https://go.basistheory.com/evervault-alternative)
    - [Basis Theory Vs. IXOPAY](https://go.basistheory.com/alternative-to-ixopay)
    - [Basis Theory Vs. VGS](https://go.basistheory.com/compare/very-good-security)

---

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Davi Aquino",
    "url" : "https://blog.basistheory.com/author/davi-aquino"
  },
  "dateModified" : "2026-03-17T14:44:40.624Z",
  "datePublished" : "2025-12-15T14:41:47.000Z",
  "headline" : "Decrypting Card Payload: Shopify Payments App",
  "image" : [ "https://blog.basistheory.com/hubfs/Decrypt%20Shopify.webp" ],
  "mainEntityOfPage" : {
    "@id" : "https://blog.basistheory.com/decrypting-card-payload-shopify-payments-app",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://blog.basistheory.com/hubfs/BTLogo%20(1).png"
    },
    "name" : "Basis Theory"
  }
}
```