Secure Proxy is a solution that allows payment integrations to transfer sensitive data (i.e.: credit card numbers) in a secure environment. An integration must use Secure Proxy if it meets the following conditions:
- It uses credit, debit, or cobranded cards as payment methods
- The environment where the connector is hosted does not have an Attestation of Compliance (AOC) of PCI - DSS (Payment Card Industry - Data Security Standard)
When an integration is PCI compliant, it does not need to use Secure Proxy, being allowed to receive sensitive data and communicate directly with the acquirer. When using Secure Proxy, the following changes occur in the flow of the integration:
- The Authorization request works as usual.
- The provider receives tokens from VTEX’s Payments Gateway that refers to the sensitive data, instead of the actual data.
- The provider sends the API endpoint of the acquirer and the merchant credentials to the Gateway.
- The Gateway makes the API call to the acquirer, acting as a proxy between the provider and the acquirer. In this call, the tokens are replaced by sensitive data.
What is PCI DSS and how is it used in VTEX?
PCI DSS is an international standard for how companies must process card information. Among the many rules of this standard is an important one that states that card information must be transferred in a secure infrastructure that has been audited by a QSA (Qualified Security Assessors) Company, which are qualified by the PCI Security Standards Council.
VTEX’s Payments Gateway service is certified by this entity to process sensitive card information, and this information can only be transferred in a secure environment in which services and partners have an AOC signed by a QSA Company. Security measures needed to meet the PCI DSS requirements include, but are not limited to the use of a firewall, encrypt the transmission of cardholder data, use of updated anti-virus, restrict access to cardholder data with authentication and monitor all access to network resources. More information about PCI DSS requirements can be found in the PCI DSS Quick Reference Guide.
Why use Secure Proxy?
Not all of VTEX’s payment ecosystem (partners and clients) have PCI DSS certification, which is required for our Payments Gateway to send card information. Besides, the VTEX IO platform is a development environment designed to accelerate the creation of new solutions for our ecosystem and we want to enable it to create payment solutions as well.
Considering that the integration environment is fundamental for a transaction to take place based on business rules about how a payment should be processed, a solution is necessary to address the scenarios in which the integration environment is not certified by PCI requirements. Therefore, Secure Proxy comes as a solution to enable new integration scenarios with VTEX’s payment partner ecosystem.
Through this solution, the Payments Gateway acts as a communication service between a payment provider in a non-PCI environment and an acquirer. The Payments Gateway sends tokenized card information to the payment provider without the risk of compromising data security. The tokens are used to replace sensitive information in the provider and to act as a reference to the information in the Gateway.
When a system does not meet all the security requirements, it might be vulnerable to attacks and data theft. This can lead to serious consequences including fraud losses, loss of confidence from customers, reduction in sales, legal costs, fines, etc. More information about these security issues can be found in the PCI article Why Security Matters. By meeting the requirements of PCI DSS, those issues and their consequences can be avoided.
Secure Proxy is mandatory for connectors built with the VTEX IO infrastructure since it is not compliant with PCI DSS. This also includes connectors made through our Payment Provider Framework.
How it works
In this section, we detail how the solution works in a payment authorization flow. The image below shows an overview of the flow containing the Secure Proxy, as well as the four steps required for the payment to be authorized by the acquirer.
1. Checkout submits a payment authorization request to the Gateway
There is no change to the current flow. The Checkout makes an Authorization request to the Gateway.
2. Gateway requests the provider to create a new payment using tokens
The Gateway makes a Create Payment request to the provider. The provider is responsible for receiving all the payment requests from the Gateway (creation, authorization, capture and cancel), regardless of using the Secure Proxy or not, and will use the defined settings in the integration including maximum time to cancel a transaction, supported payment methods, etc.
Below is an example of a payment creation request using a non-PCI payment provider. In this solution, there is a secureProxyUrl
field containing the API that the payment provider must call when communicating with the acquirer. In addition, all sensitive card information has been tokenized by the Gateway.
Request body
_16{_16 ...,_16 "secureProxyUrl": "https://account.vtexpayments.com.br/.../proxy",_16 "card": {_16 "holderToken": "#vtex#token#d799bae#holder#",_16 "bin": "555544",_16 "numberToken": "#vtex#token#d799bae#number#",_16 "numberLength": 16,_16 "cscToken": "#vtex#token#d799bae#csc#",_16 "cscLength": 3,_16 "expiration": {_16 "month": "02",_16 "year": "2028"_16 }_16 }_16}
The response body for this request can be seen in our API Reference.
3. Provider calls the Gateway to use the Secure Proxy
The provider makes a POST https://account.vtexpayments.com.br/.../proxy
call to the Gateway. This is the endpoint provided in the secureProxyUrl
field. This step occurs as follows:
- The payment provider creates the object that will be sent to the acquirer using the tokenized data submitted by the Gateway in the corresponding fields. For this request to be transferred to the acquirer, you must submit the URL you would like to use in the
X-PROVIDER-Forward-To
header. Once this is done, the Gateway will:- Verify if the URL is in the list of PCI-certified URLs.
- Replace the tokens placed in the card fields.
- Submit the request to the acquirer.
- In case custom headers must be submitted to the acquirer, add
X-PROVIDER-Forward-
as a prefix, for instanceX-PROVIDER-Forward-MerchantId
. The Gateway will remove the prefix and submit the headers. - The response body will be forwarded from the external gateway or acquirer to the payment provider.
Possible response errors
The possible known errors are:
- Error 400: the submission URL is not specified in the header.
- Error 400: the integration transfers data not recognized by the Payments Gateway in the tokenized fields (
holderToken
,numberToken
,cscToken
). - Error 403: the submission URL of the request is not allowed.
- Error 500: the Gateway cannot respond due to an internal failure.
The external gateway or acquirer also can respond with their own 4XX or 5XX errors.
You must open a ticket asking to add the acquirer’s endpoint (the one used in the
X-PROVIDER-Forward-To
header) in the VTEX’s allowed list of endpoints along with the AOC of the acquirer. If a request is made to the acquirer’s endpoint and it is not on the allowed list, it will result in an error.
Request header
_10Accept: application/json_10Content-Type: application/json_10User-Agent: HttpClient-1.0_10X-PROVIDER-Forward-To: https://apisandbox.acquirer.com/v2/sales/_10X-PROVIDER-Forward-MerchantId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_10X-PROVIDER-Forward-MerchantKey: 012345678901234567890123456789012345678
Requests to the PCI Proxy only accept two options for Content-Types:
application/json
orapplication/x-www-form-urlencoded
. Other Content-Type options are not supported, but if you need any other for an integration you can share your use case with the product team by opening a ticket to the VTEX support team.
Request body
_14{_14 "MerchantOrderId": "123456789",_14 "Customer": { ... },_14 "Payment": {_14 ...,_14 "CreditCard": {_14 "Holder": "#vtex#token#d799bae#holder#",_14 "CardNumber": "#vtex#token#d799bae#number#",_14 "ExpirationDate": "02/2028",_14 "SecurityCode": "#vtex#token#d799bae#csc#",_14 ..._14 },_14 "Credentials": { ... }_14}
Secure Proxy only supports HTTP-API (REST) integrations, which means it does not support Webservice (SOAP) or any other type of communication protocol.
4. Requests for external gateways or acquirers in a PCI environment
An example request that the Gateway will submit to the acquirer: POST https://apisandbox.acquirer.com/v2/sales/
.
Request header
_10Accept: application/json_10Content-Type: application/json_10User-Agent: HttpClient-1.0_10MerchantId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_10MerchantKey: 012345678901234567890123456789012345678
Default headers:
- Accept
- Content-Type
- User-Agent
Custom headers:
- MerchantId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- MerchantKey: 012345678901234567890123456789012345678
Request body
_14{_14 "MerchantOrderId": "123456789",_14 "Customer": { ... },_14 "Payment": {_14 ...,_14 "CreditCard": {_14 "Holder": "JOHN DOE",_14 "CardNumber": "5555444433331111",_14 "ExpirationDate": "02/2028",_14 "SecurityCode": "123",_14 ..._14 },_14 "Credentials": { ... }_14}
This request has a timeout of 15 seconds. It means that the Gateway will wait 15 seconds for the response of the acquirer and respond back to the payment provider.
Custom Tokens
As illustrated in the example above, card fields are the most often used tokens. However, the Secure Proxy also supports the creation and usage of custom tokens. This is done via the secureProxyTokensURL
field, which is included by the Gateway in the request body of Create Payment request to the payment provider. The field contains the path to the endpoint that allows dealing with custom tokens.
In the following examples, the secureProxyTokensURL
field will have the value https://{{account}}.vtexpayments.com.br/payment-provider/transactions/{{transactionId}}/payments/{{paymentId}}/tokens?hash={{longSecureHash}}
.
Access Tokens
The list of all tokens created for a payment can be fetched via a GET request to the secureProxyTokensURL
. By default, the list will only include the immutable credit card information tokens (number
, holder
and csc
) created by the Gateway.
Response body
_16{_16 "tokens": [_16 {_16 "name": "number",_16 "placeholder": "#vtex#number#{secureHash}#"_16 },_16 {_16 "name": "holder",_16 "placeholder": "#vtex#holder#{secureHash}#"_16 },_16 {_16 "name": "csc",_16 "placeholder": "#vtex#csc#{secureHash}#"_16 }_16 ]_16}
The secureHash
is a short string used for authentication during the access to a specific payment within the Secure Proxy, such as d799bae
, as previously illustrated in this example.
Create custom tokens
New tokens can be created via a POST request to the secureProxyTokensURL
. After being created, these can be referenced inside requests to the Secure Proxy and will be replaced by their values before the requests are forwarded to the acquirer.
Custom tokens allow, for example, the creation of tokens whose values are derived from credit card information.
The creation request should include a list of tokens to be created, where each one consists of a name
and a value
. The first will be included in the placeholder used to reference the token (as mentioned above) and the second will be a JsonLogic expression that describes its value. In the value
field for each token in the request body, every string must be encoded in the UTF-8 format.
Request body
_16{_16 "tokens": [_16 {_16 "name": "newToken",_16 "value": { "==": [1, 1] }_16 },_16 {_16 "name": "hashedCardNumber",_16 "value": {_16 "md5": {_16 "replaceTokens": ["#vtex#number#{secureHash}#"]_16 }_16 }_16 }_16 ]_16}
In the example request above, two new tokens are created.
- The first token is created from a simple expression and its value is evaluated to be true.
- The second token has an expression that uses custom Secure Proxy operators to compute the MD5 hash of the card number. This is done by detokenizing the card number token with the
replaceTokens
operator and then applying the MD5 operator to the result.
Response body
_12{_12 "tokens": [_12 {_12 "name": "newToken",_12 "placeholder": "#vtex#newToken#{secureHash}#"_12 },_12 {_12 "name": "hashedCardNumber",_12 "placeholder": "#vtex#hashedCardNumber#{secureHash}#"_12 }_12 ]_12}
The response consists of a list of the tokens that were created. The placeholder
can then be used inside requests to the Secure Proxy to reference the values specified by the expression of the token.
A
placeholder
can be referenced in the body or as a header in a request to the Secure Proxy.
Custom supported operators
Aside from the default JsonLogic operators, the Secure Proxy also provides support to the following operators:
replaceTokens
: given a string, replaces the tokens in it by their respective values.base64
: given a string, encode in Base64.hmac-sha256
: given two UTF-8 encoded string arguments, computes the HMAC-SHA256 hash considering the first string argument as the key and the second as the data to be hashed. The default result is Base64-encoded by default.- Optionally, a third parameter may be specified to choose the desired format of the output. The available options are
"base64"
(default) and"hex"
. - Also optionally, a fourth parameter can be specified to choose the format of the key. The available options are
“plainText”
(default),"hex”
and"base64”
.
- Optionally, a third parameter may be specified to choose the desired format of the output. The available options are
- Other hashing operators:
md5
,sha1
,sha256
,sha384
,sha512
.- Given a string, it computes the hash and returns the hex digest.
- For these hashing operators, the result is the hex digest.
- These hashing operators also have a second optional parameter to enable the user to choose the desired output to be a Hex digest output or a Base64 output. The parameter is case-insensitive and, if it is used, then it must be the string
"hex"
or the string"base64"
. If the optional parameter is not used, the default output is the hex digest.
Example of the creation of a token named "example-signature"
with a hmac-sha256
hash as its value:
_15{_15 "tokens":[_15 {_15 "name":"example-signature",_15 "value":{_15 "hmac-sha256":[_15 "this-is-the-key-value",_15 "this-is-the-data-value",_15 "this-is-the-optional-parameter-output-format",_15 "this-is-the-optional-parameter-key-format"_15 ]_15 }_15 }_15 ]_15}
Example of the creation of a token named "example-signature-2"
with a MD5 hash as its value:
_13{_13 "tokens":[_13 {_13 "name":"example-signature-2",_13 "value":{_13 "md5":[_13 "this-is-the-data-value",_13 "this-is-the-optional-parameter-base64-or-hex-output"_13 ]_13 }_13 }_13 ]_13}
Example of the creation of a token named "example-base64"
with a Base64 hash as its value:
_12{_12 "tokens":[_12 {_12 "name":"example-base64",_12 "value":{_12 "base64":[_12 "string-to-be-encoded"_12 ]_12 }_12 }_12 ]_12}
Known issues
The operator cat
from the JSONLogic library may misbehave when concatenating dates. It may change the date format.