Skip to main content

Migrating from a Server SDK Integration

The GraphQL API uses a different format for IDs than in previous Braintree APIs.

If you plan to migrate an existing SDK integration to an integration with the GraphQL API, you will also need to migrate from using Braintree legacy IDs to using GraphQL IDs. This guide details a typical migration path to achieve this.

Legacy vs. GraphQL IDs

Legacy IDs refer to the IDs currently accepted and returned by the Braintree SDKs. GraphQL IDs represent the same entities in the Braintree system, but include more information about the entity that make the GraphQL API more powerful. For example, instances of different domain objects may have the same legacy ID (e.g. a Transaction and a PaymentMethod may share an ID). GraphQL IDs are unique across all domains.

Types that implement the Node interface in the GraphQL API contain a legacyId field for the purposes of migrating from those legacy IDs to the GraphQL IDs. We also provide a query, idFromLegacyId, for translating a legacy ID to a GraphQL ID.

Migrating an Integration to Use the Braintree GraphQL API

  1. Update your database schema to store an additional "GraphQL ID" field alongside any ID fields that you currently store from Braintree. For example, if you have a transactions table with an id field, you should add a column or field named graphql_id.
  2. Build your Braintree GraphQL Integration.

    1. When reading an ID from your database, prefer to read the graphql_id instead of id.
    2. If the graphql_id is not set in your database, use the idFromLegacyId query to translate your id to a GraphQL ID. Store this id as graphql_id in your database, and use it when providing id in any GraphQL mutation or query.
  3. Always request both the id and legacyId in your API requests and dual-write these IDs in your local database. This will give you the flexibility to seamlessly switch back to your SDK integration, should the need arise.
  4. After you successfully launch your Braintree GraphQL API integration, you can back-fill your legacy IDs with GraphQL IDs using the idFromLegacyId query.
  5. Once your GraphQL integration is stable, you can stop requesting and writing the legacyId. From now on, use only the GraphQL IDs from your new integration.

Using the idFromLegacyId Query

The idFromLegacyId query takes a legacy ID and the object type and returns its GraphQL ID, for use in the GraphQL API.


query IdFromLegacyId($legacyId: ID!, $type: LegacyIdType!) {
  idFromLegacyId(legacyId: $legacyId, type: $type)


  "legacyId": "vsx5py3",
  "type": "TRANSACTION"


  "data": {
    "idFromLegacyId": "dHJhbnNhY3Rpb25fdnN4NXB5Mw"
  "extensions": {
    "requestId": "S9mAxXwoOWeQ8GOZCVTxriMrNmcSWUeAByLYcBTyt-4iHC4G_kOgjQ=="

GraphQL ID Format

In order to avoid interruptions in processing, it's best to make minimal assumptions about what GraphQL IDs will look like in the future. The format of the GraphQL ID is not a contract. While any given ID will never change, the new IDs may follow a different format in the future.

The length and format of these identifiers – including payment method tokens and transaction IDs – can change at any time, with or without advance notice. However, it is safe to assume that they will remain 1 to 256 characters (alphanumeric, dashes, and underscores).

API concepts vs. SDK concepts

Some key terms and modeling differ between the API and SDKs.

Nonces vs. single-use payment methods

The SDKs distinguish between nonces (single-use payment data collected from the client) and payment methods (vaulted payment data that may be re-used).

The API refers all payment data as a payment methods. Payment methods can be single-use (the equivalent of a nonce in the SDK) or multi-use (the equivalent of a vaulted payment method in the SDK). The usage field on a payment method indicates whether it is single- or multi-use.

nonce single-use payment method
payment method multi-use payment method

Creating transactions

In the SDKs, the sale method authorizes a payment method and optionally captures the transaction via the submit_for_settlement flag. The API provides mutations to authorize or charge payment methods, which return transactions. It also provides mutations for capturing authorized transactions.

Here is an example of a sale transaction in the Ruby SDK:

Ruby SDK

result =
  :amount => "10.00",
  :payment_method_nonce => nonce_from_the_client,
  :options => {
    :submit_for_settlement => true


mutation ExampleCharge($input: ChargePaymentMethodInput!) {
  chargePaymentMethod(input: $input) {
    transaction {
  "input": {
    "paymentMethodId": "nonce_from_the_client",
    "transaction": {
      "amount": "10.00"

Accepting payment data directly

Note this guidance is only relevant to merchants who are in PCI scope and handle raw payment details.

The SDKs allow raw credit card details as input to sale and vault requests. The API only accepts raw payment details via the tokenization mutations. To charge or vault credit card details directly, tokenize and then use the resulting payment method in a vault or charge mutation.