curl --request POST \
--url https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cardNumber": "tok_sandbox_x7Kq2mP9vL4n",
"cvv": "tok_sandbox_b3Rt8wQ1",
"expiry_month": 12,
"expiry_year": 2030,
"last4": "4242",
"brand": "visa",
"bin": "424242",
"cardholder_name": "Ada Lovelace",
"billing_postal_code": "94110"
}
'import requests
url = "https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm"
payload = {
"cardNumber": "tok_sandbox_x7Kq2mP9vL4n",
"cvv": "tok_sandbox_b3Rt8wQ1",
"expiry_month": 12,
"expiry_year": 2030,
"last4": "4242",
"brand": "visa",
"bin": "424242",
"cardholder_name": "Ada Lovelace",
"billing_postal_code": "94110"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
cardNumber: 'tok_sandbox_x7Kq2mP9vL4n',
cvv: 'tok_sandbox_b3Rt8wQ1',
expiry_month: 12,
expiry_year: 2030,
last4: '4242',
brand: 'visa',
bin: '424242',
cardholder_name: 'Ada Lovelace',
billing_postal_code: '94110'
})
};
fetch('https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cardNumber' => 'tok_sandbox_x7Kq2mP9vL4n',
'cvv' => 'tok_sandbox_b3Rt8wQ1',
'expiry_month' => 12,
'expiry_year' => 2030,
'last4' => '4242',
'brand' => 'visa',
'bin' => '424242',
'cardholder_name' => 'Ada Lovelace',
'billing_postal_code' => '94110'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm"
payload := strings.NewReader("{\n \"cardNumber\": \"tok_sandbox_x7Kq2mP9vL4n\",\n \"cvv\": \"tok_sandbox_b3Rt8wQ1\",\n \"expiry_month\": 12,\n \"expiry_year\": 2030,\n \"last4\": \"4242\",\n \"brand\": \"visa\",\n \"bin\": \"424242\",\n \"cardholder_name\": \"Ada Lovelace\",\n \"billing_postal_code\": \"94110\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cardNumber\": \"tok_sandbox_x7Kq2mP9vL4n\",\n \"cvv\": \"tok_sandbox_b3Rt8wQ1\",\n \"expiry_month\": 12,\n \"expiry_year\": 2030,\n \"last4\": \"4242\",\n \"brand\": \"visa\",\n \"bin\": \"424242\",\n \"cardholder_name\": \"Ada Lovelace\",\n \"billing_postal_code\": \"94110\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cardNumber\": \"tok_sandbox_x7Kq2mP9vL4n\",\n \"cvv\": \"tok_sandbox_b3Rt8wQ1\",\n \"expiry_month\": 12,\n \"expiry_year\": 2030,\n \"last4\": \"4242\",\n \"brand\": \"visa\",\n \"bin\": \"424242\",\n \"cardholder_name\": \"Ada Lovelace\",\n \"billing_postal_code\": \"94110\"\n}"
response = http.request(request)
puts response.read_body{
"object": "payment_method_session",
"id": "pms_test_7Hs2kQ9mL1pXv4cR8tWzAbCd",
"status": "requires_payment_method",
"customer": null,
"payment_method_types": [
"card"
],
"amount": null,
"currency": null,
"livemode": false,
"expires_at": "2026-09-17T18:30:00.000Z",
"canceled_at": null,
"succeeded_at": null,
"card": null,
"us_bank_account": null,
"acss_debit": null,
"ach_authorization": null,
"pad_agreement": null,
"payment_method": null,
"created_at": "2026-09-17T18:00:00.000Z"
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}Confirm a payment method session
Called by Payra Elements once the customer submitted the fields or paid in a wallet sheet: it closes the session with the collected card, with the collected bank account and the authorization the account holder accepted (the ACH authorization on a US account, the pre-authorized debit agreement on a Canadian one), or with the token the wallet handed over. With a publishable key it needs the session client_secret; a secret key may call it too, except for a Canadian bank account, which is only accepted from the secure fields of Payra Elements. Card and bank details arrive through the secure route, tokenized; anything else is refused and never stored. A bank account without the acceptance is refused too. A wallet token is checked for shape and size and never read.
curl --request POST \
--url https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"cardNumber": "tok_sandbox_x7Kq2mP9vL4n",
"cvv": "tok_sandbox_b3Rt8wQ1",
"expiry_month": 12,
"expiry_year": 2030,
"last4": "4242",
"brand": "visa",
"bin": "424242",
"cardholder_name": "Ada Lovelace",
"billing_postal_code": "94110"
}
'import requests
url = "https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm"
payload = {
"cardNumber": "tok_sandbox_x7Kq2mP9vL4n",
"cvv": "tok_sandbox_b3Rt8wQ1",
"expiry_month": 12,
"expiry_year": 2030,
"last4": "4242",
"brand": "visa",
"bin": "424242",
"cardholder_name": "Ada Lovelace",
"billing_postal_code": "94110"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
cardNumber: 'tok_sandbox_x7Kq2mP9vL4n',
cvv: 'tok_sandbox_b3Rt8wQ1',
expiry_month: 12,
expiry_year: 2030,
last4: '4242',
brand: 'visa',
bin: '424242',
cardholder_name: 'Ada Lovelace',
billing_postal_code: '94110'
})
};
fetch('https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'cardNumber' => 'tok_sandbox_x7Kq2mP9vL4n',
'cvv' => 'tok_sandbox_b3Rt8wQ1',
'expiry_month' => 12,
'expiry_year' => 2030,
'last4' => '4242',
'brand' => 'visa',
'bin' => '424242',
'cardholder_name' => 'Ada Lovelace',
'billing_postal_code' => '94110'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm"
payload := strings.NewReader("{\n \"cardNumber\": \"tok_sandbox_x7Kq2mP9vL4n\",\n \"cvv\": \"tok_sandbox_b3Rt8wQ1\",\n \"expiry_month\": 12,\n \"expiry_year\": 2030,\n \"last4\": \"4242\",\n \"brand\": \"visa\",\n \"bin\": \"424242\",\n \"cardholder_name\": \"Ada Lovelace\",\n \"billing_postal_code\": \"94110\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"cardNumber\": \"tok_sandbox_x7Kq2mP9vL4n\",\n \"cvv\": \"tok_sandbox_b3Rt8wQ1\",\n \"expiry_month\": 12,\n \"expiry_year\": 2030,\n \"last4\": \"4242\",\n \"brand\": \"visa\",\n \"bin\": \"424242\",\n \"cardholder_name\": \"Ada Lovelace\",\n \"billing_postal_code\": \"94110\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-dashboard.payra.com/v1/payment-method-sessions/{id}/confirm")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"cardNumber\": \"tok_sandbox_x7Kq2mP9vL4n\",\n \"cvv\": \"tok_sandbox_b3Rt8wQ1\",\n \"expiry_month\": 12,\n \"expiry_year\": 2030,\n \"last4\": \"4242\",\n \"brand\": \"visa\",\n \"bin\": \"424242\",\n \"cardholder_name\": \"Ada Lovelace\",\n \"billing_postal_code\": \"94110\"\n}"
response = http.request(request)
puts response.read_body{
"object": "payment_method_session",
"id": "pms_test_7Hs2kQ9mL1pXv4cR8tWzAbCd",
"status": "requires_payment_method",
"customer": null,
"payment_method_types": [
"card"
],
"amount": null,
"currency": null,
"livemode": false,
"expires_at": "2026-09-17T18:30:00.000Z",
"canceled_at": null,
"succeeded_at": null,
"card": null,
"us_bank_account": null,
"acss_debit": null,
"ach_authorization": null,
"pad_agreement": null,
"payment_method": null,
"created_at": "2026-09-17T18:00:00.000Z"
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}{
"error": {
"type": "invalid_request_error",
"code": "<string>",
"message": "<string>",
"request_id": "<string>",
"param": "<string>"
}
}Authorizations
A secret key, sk_test_... or sk_live_...; a publishable key (pk_...) on the browser routes only
Path Parameters
1 - 64Query Parameters
Required with a publishable key: the secret returned when the session was created.
Body
- Option 1
- Option 2
- Option 3
- Option 4
A card, a US bank account with its ACH authorization, a Canadian bank account with its pre-authorized debit agreement, or a wallet token, by what the session collects.
The card number as tokenized by the inbound route.
1 - 128"tok_sandbox_x7Kq2mP9vL4n"
The security code as tokenized by the inbound route. The vault may alias it as digits of the same length.
1 - 128"tok_sandbox_b3Rt8wQ1"
1 <= x <= 1212
2030
^\d{4}$"4242"
20"visa"
^\d{6,8}$"424242"
First and last name, as on the card.
1 - 255"Ada Lovelace"
^(?:\d{5}(?:-\d{4})?|[ABCEGHJ-NPRSTVXYabceghj-nprstvxy]\d[ABCEGHJ-NPRSTV-Zabceghj-nprstv-z] ?\d[ABCEGHJ-NPRSTV-Zabceghj-nprstv-z]\d)$"94110"
What the page knows of the browser, for 3-D Secure; Payra adds the user agent from the request.
Show child attributes
Show child attributes
Response
The session, now succeeded, with the card the merchant may see
payment_method_session "pms_test_7Hs2kQ9mL1pXv4cR8tWzAbCd"
requires_payment_method, succeeded, canceled, expired "requires_payment_method"
null
card, us_bank_account, acss_debit, apple_pay, google_pay ["card"]
What a one-time bank debit will authorize, or what a wallet sheet shows, in the smallest unit of currency. Null on a card session and when a bank account is being saved.
null
USD on a us_bank_account session, CAD on an acss_debit one, either on a wallet session.
USD, CAD null
false
"2026-09-17T18:30:00.000Z"
null
null
Set once the browser confirmed a card, or a wallet confirmed with its card.
Show child attributes
Show child attributes
null
Set once the browser confirmed a US bank account.
Show child attributes
Show child attributes
null
Set once the browser confirmed a Canadian bank account.
Show child attributes
Show child attributes
null
On a us_bank_account session: the authorization shown to the account holder, and when they accepted it.
Show child attributes
Show child attributes
null
On an acss_debit session: the pre-authorized debit agreement shown to the account holder, and when they accepted it.
Show child attributes
Show child attributes
null
The payment method your server created from this session, once it did.
null
"2026-09-17T18:00:00.000Z"