Skip to main content

Payment Methods

Important changes on the Public API

When creating transactions and payment sources, and because we keep our users privacy in the top of our priorities, the usage of Acceptance Tokens is now mandatory when creating either of these resources through our API.

Every time you create a transaction using our API, you have the option of processing the payment using different payment methods. Currently, the available payment methods are:

  • Credit or Debit Cards: Allows your customers to pay using credit or debit cards.
  • Clave: Offer your customers the possibility to use their Key card to complete the payment

To use a payment method you must POST in the /transactions endpoint with:

  1. Specify the payment_method field with a JSON object containing specific details for each method, described below.

To end the payment process for any of the available payment methods, we recommend periodically verifying (long polling) the state of a transaction, waiting for a final status (approved, denied, voided or error), using the transaction ID and our API, since none of the payment methods deliver an instant synchronous response. A transaction that has just been created always has a PENDING status.

Final statuses for a transaction

The final status of a transaction can be: APPROVED (approved) , DECLINED (declined), VOIDED (anulled, applies to transactions with card only) or ERROR (if there is an external error with a payment method during the transaction).

Credit or Debit Cards

In Wompi, your customers can process payments using a Visa or Mastercard Credit or Debit Card, as long as the card has a CVC (card verification code), usually printed on the back of the card.

The payment method type that you must use to create the transaction is CARD. When using the payment method CARD you need to take into account that:

  1. You must first tokenize a card (more details below).
  2. You must ask the end how many installments does he wants to make his payment.

Never store card sensitive data!
We completely discourage the storage of card sensitive data on your end. Not only you risk your users' data, but you can face economic sanctions and legal problems. Wompi has a PCI DSS certification for securely handling, transmitting and processing card sensitive data, therefore preventing businesses from storing this data, by using only safely generated card tokens.

Tokenize a Credit or Debit Card

By default we recommend tokenizing by encrypting the card information. If your use case does not support encryption, select the simple tokenization tab.

The steps to tokenize while encrypting the card information are:

  1. Get the public key (GET /v1/tokens/keys/tokenization).
  2. Generate the JWE with RSA-OAEP-256 and CEK AES-GCM-256.
  3. Send the payload (the JWE as a string) to POST /v1/tokens/cards.

To tokenize by encrypting the information, first generate a JWE (JSON Web Encryption) with the card information and send it in the payload field.

The public key required to generate the JWE —which uses the RSA-OAEP algorithm— can be obtained from the following endpoint:

GET /v1/tokens/keys/tokenization

To tokenize a card, send the encrypted card information to the following endpoint.

POST /v1/tokens/cards
Authentication header

Use your merchant public key in the authorization header.
As "Authorization": "Bearer [merchant's public key]"

The JWE must be sent in the payload field as a base64 string and for the JWE CEK (Content Encryption Key) you must use AES GCM 256. Assuming a function encrypt_jwe, which generates the JWE from the card information, the public key, and the algorithm to use in the CEK, you must send the following information to the endpoint:

{
"payload": encrypt_jwe(
{
"number": "4242424242424242", // Card number
"cvc": "123", // Card security code (3 or 4 digits depending on the brand)
"exp_month": "08", // Expiration month (2-digit string)
"exp_year": "28", // Year expressed as 2 digits
"card_holder": "Jose Perez" // Cardholder name
},
ENCRYPTION_PUBLIC_KEY,
"RSA-OAEP-256"
)
}

The successful v1/tokens/cards response looks like this:

{
"status": "CREATED",
"data": {
"id": "tok_prod_1_BBb749EAB32e97a2D058Dd538a608301", // TOKEN that must be used to create the transaction
"created_at": "2020-01-02T18:52:35.850+00:00",
"brand": "VISA",
"name": "VISA-4242",
"last_four": "4242",
"bin": "424242",
"exp_year": "28",
"exp_month": "08",
"card_holder": "Jose Perez",
"expires_at": "2020-06-30T18:52:35.000Z"
}
}

Examples in different languages:

BASE_URL

For Panama use https://api.wompi.pa/v1 as BASE_URL in the examples.

encrypt.js
import { pathToFileURL } from 'url'
import { importSPKI, EncryptJWT } from 'jose'

const BASE_URL = '<BASE_URL>'
const WOMPI_PUBLIC_KEY = '...'

const cardInfo = {
number: '4242424242424242',
exp_month: '04',
exp_year: '30',
cvc: '123',
card_holder: 'test test',
}

let cachedPublicKey

async function getPublicKey() {
if (cachedPublicKey) return cachedPublicKey

const response = await fetch(`${BASE_URL}/tokens/keys/tokenization`, {
headers: {
Authorization: `Bearer ${WOMPI_PUBLIC_KEY}`,
'Content-Type': 'application/json',
},
})

if (!response.ok) {
const body = await response.text()
throw new Error(`Unable to fetch public key. Status ${response.status}: ${body}`)
}

const body = await response.json()
const publicKeyPem = body?.data?.publicKey
if (!publicKeyPem) throw new Error('Public key missing in response')

cachedPublicKey = publicKeyPem
return cachedPublicKey
}

async function tokenizeCard(payload) {
const response = await fetch(`${BASE_URL}/tokens/cards`, {
method: 'POST',
headers: {
Authorization: `Bearer ${WOMPI_PUBLIC_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
})

const body = await response.json()
if (!response.ok) {
throw new Error(
`Tokenization failed - Status ${response.status}: ${JSON.stringify(body)}`
)
}

return body
}

export async function encryptCardInfo(cardInfo, pubKey) {
const secret = await importSPKI(pubKey, 'RSA-OAEP-256')
const encryptedData = await new EncryptJWT(cardInfo)
.setProtectedHeader({ alg: 'RSA-OAEP-256', enc: 'A256GCM' })
.encrypt(secret)

return encryptedData
}

const main = async () => {
try {
const publicKey = await getPublicKey()
const encrypted = await encryptCardInfo(cardInfo, publicKey)
console.log("encypted:", encrypted)
const tokenizationResponnse = await tokenizeCard({ payload: encrypted })
console.log(tokenizationResponnse)
return tokenizationResponnse
} catch (error) {
console.error('Tokenization failed:', error)
process.exitCode = 1
}
}

if (import.meta.url === pathToFileURL(process.argv[1]).href) {
main()
}
Don't use a token more than once!

If you need to create multiple transactions for the same card, use the Payment Sources feature.

Create the Transaction

After obtaining the token details and having asked the user the number of ("installments"). The payment method fields for a new transaction with a card should be similar to the following:

{
"payment_method": {
"type": "CARD",
"installments": 1, // Number of installments
"token": "tok_prod_e6S2sAz383mdCQ38dj32z" // Card token
}
// Other transaction fields...
}

Lastly, remember to periodically check the state of the transacion in Wompi from your system, using the transaction ID and our API endpoint GET /v1/transactions/:id.

Clave

We will guide you through the process of using the Clave payment method in our API. Clave is a card system belonging to the company Telered in Panama, offering your customers a secure way to process payments on your platform.

Create transaction

To get started with the Clave payment method, you need to create a new transaction using the endpoint POST /v1/transactions. Make sure to include the following specific fields for the Clave payment method:

{
"payment_method": {
"type": "CLAVE"
},
// Other transaction fields...
"amount_in_cents": 2000,
"currency": "USD",
"customer_email": "{{EMAIL}}",
"reference": "{{REFERENCE}}",
"acceptance_token" : "{{ACCEPTANCE_TOKEN}}"
}

Check transaction

After creating the transaction, it's essential to periodically check for changes in the transaction using the Wompi API and the transaction ID. You can do this by using the endpoint GET /v1/transactions/<TRANSACTION_ID>.

Once you receive the response, you should validate the data->payment_method->extra->clave_auth->url field. This URL should be loaded into an <iframe> element within your payment page. Here, your customers will interact with the Clave system to continue the transaction process. Upon successfully completing the process, the data->status field will change to APPROVED, DECLINED, or ERROR, depending on the outcome.

Below is an example of the response structure:

{
"data": {
"id": "1156-1689191638-98479",
"created_at": "2023-07-12T19:53:58.190Z",
"amount_in_cents": 1000,
"reference": "refence_test1",
"currency": "USD",
"payment_method_type": "CLAVE",
"payment_method": {
"type": "CLAVE",
"extra": {
"clave_auth": {
"url": "URL_TEST",
"session_id": "12345",
"client_session_id": "12345"
}
}
},
"redirect_url": null,
"status": "PENDING",
"status_message": null,
"merchant": {
"name": "Comercio De Prueba",
"legal_name": "Comercio De Prueba",
"contact_name": "Pepito Perez",
"phone_number": "+507123456789",
"logo_url": null,
"legal_id_type": "RUC",
"email": "test@wompi.com",
"legal_id": "123456789-1"
},
"taxes": []
},
"meta": {}
}

Simple Payment Clave