Skip to content

Update card

PATCH
/card

Update the card status, installments mode, or PIN, or submit a signed challenge to bind the card to the authenticated user.

Updating the card status

  • ACTIVE: The card is active and can be used.
  • FROZEN: The card is frozen and cannot be used but may be active in the future.
  • DELETED: The card is deleted and cannot be used permanently.

Updating the card PIN

  1. Encrypt the PIN: Format and encrypt the PIN using the session secret.
  2. Submit the update: Send the encrypted PIN with the sessionId to update the card.

Submitting a signature

Use method: "siwe" or method: "webauthn" to verify the challenge previously obtained from GET /?scope=.... On success the response is { "verification": "OK" }; an invalid or unverifiable signature returns { "code": "bad signature" } with HTTP 400.

  • siwe: Sign the SIWE message with the account’s wallet and submit { method: "siwe", message, signature }. The server checks the message’s statement, domain, and chainId against the expected values, validates the signature on-chain, and forwards it to the provider.
  • webauthn: Sign the statement with a passkey and submit { method: "webauthn", assertion }, where assertion is the WebAuthn assertion (id, rawId, response, clientExtensionResults, type).

PIN Requirements

  • Length must be between 4–12 digits.
  • No simple sequences (e.g., 1234, 0000)
  • No repeated numbers (e.g., 1111, 2222)

PIN Encryption Format

async function encryptPIN(pin: string) {
  if (pin.length < 4 || pin.length > 12) throw new Error("PIN must be between 4–12 digits");
  const data = `2${pin.length.toString(16)}${pin}${"F".repeat(14 - pin.length)}`;

  const secret = crypto.randomUUID().replaceAll("-", "");
  const secretKeyBase64 = Buffer.from(secret, "hex").toString("base64");
  const secretKeyBase64Buffer = Buffer.from(secretKeyBase64, "utf8");
  const secretKeyBase64BufferEncrypted = crypto.publicEncrypt(
    { key: pem, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING },
    secretKeyBase64Buffer,
  );
  const sessionId = secretKeyBase64BufferEncrypted.toString("base64");

  const iv = crypto.randomBytes(12);
  const cipher = crypto.createCipheriv("aes-128-gcm", Buffer.from(secret, "hex"), iv);
  const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
  const authTag = cipher.getAuthTag();

  return {
    data: Buffer.concat([encrypted, authTag]).toString("base64"),
    iv: iv.toString("base64"),
    sessionId,
  };
}
Any of:
object
mode
required
integer
<= 9

Card updated

Any of:
object
data
required
string
iv
required
string

Bad request

Any of:
object
code
required
Allowed values: bad request

Forbidden

object
code
required
Allowed values: no panda

Not found

object
code
required
Allowed values: no card