For some use cases, it may not make sense to collect payment info using the rye-pay library. Perhaps you already have saved payment info, or you have another payment provider or integration configured. For these types of scenarios, it’s still possible to use the Rye API to submit an order by manually tokenizing a credit card and submitting it as part of the submitCart input.

At a glance

  • All the operations from this guide can be executed on the backend and do not require client-side code
  • A tokenized credit card must be submitted as part of the submitCart input. This is the card that will be charged for the purchase

Step-by-step guide

1. Create a cart

First, we need to create a cart with at least one item in it. This can be done using the createCart operation. Be sure to grab the cart id from the response, as we’ll need it for our next steps.

mutation CreateCart ($input: CartCreateInput!) {
	createCart(input: $input) {
		cart {
			id
			stores {
				... on ShopifyStore {
					store
					cartLines {
						quantity
						variant {
							id
						}
					}
				}
			}
		}
	}
}

2. Update the cart’s buyer identity

Now we need to update the cart’s buyer identity. The buyer identity is essentially information about the customer who we’re creating the cart for. Their information will be used to calculate shipping costs and taxes, and ultimately for shipping the order. Because of this, be sure to use an actual valid phone number and address. We can use the updateCartBuyerIdentity mutation. Note that we’re also requesting errors back in the response just in case we have an issue with phone number or address validation.

mutation UpdateCartBuyerIdentity ($input: CartBuyerIdentityUpdateInput!) {
	updateCartBuyerIdentity(input: $input) {
		cart {
			id
			stores {
				... on ShopifyStore {
					store
					cartLines {
						quantity
						variant {
							id
						}
					}
				}
			}
            buyerIdentity {
                firstName
                lastName
                address1
                address2
                city
                provinceCode
                countryCode
                postalCode
                email
                phone
            }
		}
        errors {
            code
            message
        }
	}
}

3. Get shipping options for the cart

Now that we know which products we’re buying, and who we’re shipping them to, we can get shipping options for the cart. Let’s call getCart, and request an offer which will include all of the relevant information we need. Choose a shipping method from the response and copy its information for later.

query GetCart ($id: ID!) {
	getCart(id: $id) {
		cart {
			id
			stores {
				... on ShopifyStore {
					store
					cartLines {
						quantity
						variant {
							id
						}
					}
                    offer {
                        shippingMethods {
                            id
                            label
                            price {
                                displayValue
                                currency
                            }
                            taxes {
                                displayValue
                                currency
                            }
                            total {
                                displayValue
                                currency
                            }
                        }
                    }
				}
			}
            buyerIdentity {
                firstName
                lastName
                address1
                address2
                city
                provinceCode
                countryCode
                postalCode
                email
                phone
            }
		}
        errors {
            code
            message
        }
	}
}

4. Use Spreedly to tokenize a credit card

Next, we need to handle payment. We’ll use Spreedly directly for this. To make things easier, your Rye account comes with a Spreedly account already set up for you! You can find your Spreedly credentials on the Rye Console Account page in the Payment Gateway Headers section.

For our example, we’ll use a test credit card, but this same process can be used for real credit cards as well. Please note that Rye will not be responsible for any fraudulent purchases, so be sure your application is secure and protects against fraud.

Be sure to grab the payment_method.token value from the response, NOT the transaction.token value. The payment_method.token represents the credit card and is what we’ll use to submit the order.

The payment_method.token expires 5-10 minutes after creation. You must tokenize the card again to submit the cart
# Be sure to update the Authorization header with your actual credentials from the Rye Console
curl --location 'https://core.spreedly.com/v1/payment_methods.json' \
--header 'Authorization: Basic YOUR_CREDENTIALS_HERE' \
--header 'Content-Type: application/json' \
--data '{
    "payment_method": {
        "credit_card": {
            "first_name": "John",
            "last_name": "Doe",
            "number": "4242424242424242",
            "verification_value": "553",
            "month": "12",
            "year": "2024",
            "retained": true
        }
    }
}'

5. Submit the cart

We now have all the information we need to submit the cart! We’ll use the submitCart mutation for this.

For our mutation, we’ll request some new fields status and requestId from the stores field. These fields will be used to track the status of the order, so be sure to take a look at the status and copy the requestId somewhere for later. We’ll also request errors back on the store level just in case we have an issue with placing the order.

mutation SubmitCart ($input: CartSubmitInput!) {
    submitCart(input: $input) {
        cart {
            id
            stores {
                status
                requestId
                store {
                    ... on ShopifyStore {
                        store
                        cartLines {
                            quantity
                            variant {
                                id
                            }
                        }
                    }
                }
                errors {
                    code
                    message
                }
            }
        }
        errors {
            code
            message
        }
        
    }
}

Congrats! You’ve successfully submitted an order via Rye using backend-only code! The requestId you copied from the response represents a Rye Checkout Request, which you can think of as an Order.

6. Check order status

Once we’ve successfully created an order, we can keep track of its status using two main methods:

  1. Polling using the orderByID query
  2. Receiving webhook updates from Rye

While option 2 is recommended in production, for simplicity we can run with option 1 for now. See the OrderStatus enum for all possible statuses.

query OrderById($id: ID!) {
    orderByID(id: $id) {
        id
        status
        events {
            id
            createdAt
            ... on OrderFailedOrderEvent { 
                reason
            }
        }
        requiredActions {
            ... on CompletePaymentChallenge {
    		    redirectURL
    	    }
        }
    }
}

Simplifying the process

Now that you’ve gone through the full process, you hopefully have a better understanding of how the Rye API works and all of the information required for submitting an order via backend-only. Good news - in your application, you might be able to get away with combining some of these steps! For example, you can combine steps 1-3 above into a single call. You can create a cart with items and buyer identity from the beginning, and the response can include the newly created cart id along with an offer with shipping options. Here’s an example:

mutation CreateCart ($input: CartCreateInput!) {
	createCart(input: $input) {
		cart {
			id
			stores {
				... on ShopifyStore {
					store
					cartLines {
						quantity
						variant {
							id
						}
					}
                    offer {
                        shippingMethods {
                            id
                            label
                            price {
                                displayValue
                                currency
                            }
                            taxes {
                                displayValue
                                currency
                            }
                            total {
                                displayValue
                                currency
                            }
                        }
                    }
				}
			}
            buyerIdentity {
                firstName
                lastName
                address1
                address2
                city
                provinceCode
                countryCode
                postalCode
                email
                phone
            }
		}
        errors {
            code
            message
        }
	}
}

Next steps

Congrats on making it this far! Here are some next steps you could take: