curl --request POST \
--url https://vault.staging.crossmint.com/api/unstable/payment-methods \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <x-api-key>' \
--data '
{
"type": "card",
"userLocator": "userId:abc123"
}
'import requests
url = "https://vault.staging.crossmint.com/api/unstable/payment-methods"
payload = {
"type": "card",
"userLocator": "userId:abc123"
}
headers = {
"X-API-KEY": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({type: 'card', userLocator: 'userId:abc123'})
};
fetch('https://vault.staging.crossmint.com/api/unstable/payment-methods', 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://vault.staging.crossmint.com/api/unstable/payment-methods",
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([
'type' => 'card',
'userLocator' => 'userId:abc123'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <x-api-key>"
],
]);
$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://vault.staging.crossmint.com/api/unstable/payment-methods"
payload := strings.NewReader("{\n \"type\": \"card\",\n \"userLocator\": \"userId:abc123\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<x-api-key>")
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://vault.staging.crossmint.com/api/unstable/payment-methods")
.header("X-API-KEY", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"card\",\n \"userLocator\": \"userId:abc123\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://vault.staging.crossmint.com/api/unstable/payment-methods")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"card\",\n \"userLocator\": \"userId:abc123\"\n}"
response = http.request(request)
puts response.read_body{
"createdAt": "2025-01-15T10:30:00.000Z",
"default": true,
"display": {
"imageUrl": "https://www.crossmint.com/assets/cards/visa.svg",
"label": "Visa ending in 4242"
},
"paymentMethodId": "3f7a9c10-2a8b-4c5d-9e2f-1b3a4c5d6e7f",
"type": "card",
"updatedAt": "2025-01-15T10:30:00.000Z"
}Create Payment Method
Save a payment method for a user so it can be used with Checkout, Onramp, and Offramp orders
curl --request POST \
--url https://vault.staging.crossmint.com/api/unstable/payment-methods \
--header 'Content-Type: application/json' \
--header 'X-API-KEY: <x-api-key>' \
--data '
{
"type": "card",
"userLocator": "userId:abc123"
}
'import requests
url = "https://vault.staging.crossmint.com/api/unstable/payment-methods"
payload = {
"type": "card",
"userLocator": "userId:abc123"
}
headers = {
"X-API-KEY": "<x-api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-KEY': '<x-api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({type: 'card', userLocator: 'userId:abc123'})
};
fetch('https://vault.staging.crossmint.com/api/unstable/payment-methods', 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://vault.staging.crossmint.com/api/unstable/payment-methods",
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([
'type' => 'card',
'userLocator' => 'userId:abc123'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-KEY: <x-api-key>"
],
]);
$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://vault.staging.crossmint.com/api/unstable/payment-methods"
payload := strings.NewReader("{\n \"type\": \"card\",\n \"userLocator\": \"userId:abc123\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-KEY", "<x-api-key>")
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://vault.staging.crossmint.com/api/unstable/payment-methods")
.header("X-API-KEY", "<x-api-key>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"card\",\n \"userLocator\": \"userId:abc123\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://vault.staging.crossmint.com/api/unstable/payment-methods")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<x-api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"card\",\n \"userLocator\": \"userId:abc123\"\n}"
response = http.request(request)
puts response.read_body{
"createdAt": "2025-01-15T10:30:00.000Z",
"default": true,
"display": {
"imageUrl": "https://www.crossmint.com/assets/cards/visa.svg",
"label": "Visa ending in 4242"
},
"paymentMethodId": "3f7a9c10-2a8b-4c5d-9e2f-1b3a4c5d6e7f",
"type": "card",
"updatedAt": "2025-01-15T10:30:00.000Z"
}Returns
Returns a PaymentMethod object.Headers
API key required for authentication
Body
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
Show child attributes
Show child attributes
Account identifier type: Mexican bank account identified by an 18-digit CLABE. type names the account identifier / capture schema Crossmint collects — never the payment rail; rail selection happens at payment execution time.
bank-account-mx-clabe Identifies the target user when authenticating with a server API key. Format: <type>:<value> (e.g., email:alice@example.com, userId:abc123, phoneNumber:+12125551234, twitter:alice). Required for API-key authentication; ignored when authenticating with a JWT (the JWT subject is used).
1Response
The payment method has been successfully created
- Option 1
- Option 2
- Option 3
- Option 4
- Option 5
Show child attributes
Show child attributes
ISO 8601 timestamp when this payment method was created.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$1Whether this destination can receive a payout right now. 'active' when a provider has confirmed a rail, 'pending' while rail resolution is still running, 'rejected' when it cannot receive funds, 'inactive' when it was deleted or disabled. Branch on this field, never on reason.
active, inactive, pending, rejected bank-account-co ISO 8601 timestamp when this payment method was last modified.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Show child attributes
Show child attributes
Read-only. ISO 8601 timestamp of the most recent successful offramp payout funded by this bank account. Absent if none.
^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$Why the status is not 'active'. Absent when it is, and on a 'pending' status other than a provider outage. Known values today: provider-unavailable, destination-not-found, destination-closed, destination-cannot-receive, no-rail-available, deleted, disabled. New codes can appear at any time, so branch on status and treat an unrecognised reason as the status alone.
Was this page helpful?

