Sell Anything API
In this tutorial, you’ll understand how to use Rye’s Sell Anything API to create a cart, add products to it, and submit it for checkout.
Requirements
- You have created a Rye Developer Account.
- You have access to your API key (Follow these steps if not).
Let’s begin!
Initialize GQL client with your API key
Use your API Key to initialize authorization headers for your GQL client.
import { GraphQLClient, gql } from 'graphql-request'
const endpoint = 'https://graphql.api.rye.com/v1/query'
const client = new GraphQLClient(endpoint)
const headers = {
// Tip: You can get these from the Rye Console, under the "Account" tab.
'Authorization': 'Basic <API Key Here>',
'Rye-Shopper-IP': 'xxx.xxx.xxx.xxx',
}
Add external product to Rye inventory
Adding product data to inventory may take a few seconds, but the product ID will be returned immediately. You can then use this product ID to fetch product data in the next step. You can also do this via the Rye Console, under the “Requests” tab.
async function requestProduct() {
const variables = {
"input": {
"url": "https://www.amazon.com/Verity-Colleen-Hoover-ebook/dp/B09H6T8LTR"
}
};
const query = gql`
mutation RequestAmazonProductByURL(
$input: RequestAmazonProductByURLInput!
) {
requestAmazonProductByURL(input: $input) {
productId
}
}
`;
const data = await client.request(query, variables, headers)
console.log(JSON.stringify(data, undefined, 2))
}
await requestProduct();
Fetch product data from Rye inventory
The product ID can be found in the response to the requestAmazonProductByURL
mutation’s response.
async function fetchProduct() {
const variables = {
"input": {
"id": "B09H6T8LTR",
"marketplace": "AMAZON"
}
};
const query = gql`
query DemoAmazonProductFetch($input: ProductByIDInput!) {
product: productByID(input: $input) {
title
vendor
url
isAvailable
images {
url
}
price {
displayValue
}
... on AmazonProduct {
ASIN
}
}
}
`;
const data = await client.request(query, variables, headers)
console.log(JSON.stringify(data, undefined, 2))
}
await fetchProduct();
Create a cart
We can create a cart containing the Amazon product we just requested.
const CREATE_CART_QUERY = gql`
mutation createCart($input: CartCreateInput!) {
createCart(input: $input) {
cart {
id
stores {
... on AmazonStore {
store
cartLines {
quantity
product {
id
}
}
offer {
subtotal {
value
currency
displayValue
}
margin {
value
currency
displayValue
}
notAvailableIds
shippingMethods {
id
label
taxes {
value
currency
displayValue
}
price {
value
currency
displayValue
}
total {
value
currency
displayValue
}
}
}
}
}
}
errors {
code
message
}
}
}
`;
const createCartWithProducts = (product) => {
const input = {
items: {}
};
if (product.marketplace === 'AMAZON') {
input.items.amazonCartItemsInput = [
{ productId: product.id, quantity: 1 },
];
}
if (product.marketplace === 'SHOPIFY') {
input.items.shopifyCartItemsInput = [
{ variantId: product.id, quantity: 1 },
];
}
input.buyerIdentity = {
city: 'city',
countryCode: 'countryCode',
provinceCode: 'provinceCode',
postalCode: 'postalCode',
};
const response = await client.request(
CREATE_CART_QUERY,
variables,
headers,
);
return response.data!.createCart.cart!;
}
const cart = await createCartWithProducts({
id: 'B09H6T8LTR',
marketplace: 'AMAZON',
})
Use a fragment
In the previous step our GraphQL document was extremely long. We can cut down on duplication by extracting our selected fields out as a reusable fragment, like so:
const CartFragment = gql`
fragment CartFragment on Cart {
id
stores {
... on AmazonStore {
store
cartLines {
quantity
product {
id
}
}
offer {
subtotal {
value
currency
displayValue
}
margin {
value
currency
displayValue
}
notAvailableIds
shippingMethods {
id
label
taxes {
value
currency
displayValue
}
price {
value
currency
displayValue
}
total {
value
currency
displayValue
}
}
}
}
}
}
`;
// Use `CartFragment` to keep `CREATE_CART_QUERY` lean
const CREATE_CART_QUERY = gql`
${CartFragment}
mutation createCart($input: CartCreateInput!) {
createCart(input: $input) {
cart {
...CartFragment
}
errors {
code
message
}
}
}
`;
// ...
Add more products to your cart
Add more products to your cart with the product IDs and the cart ID of the desired cart, using the addCartItems
mutation.
const ADD_CART_ITEMS_QUERY = gql`
${CartFragment}
mutation addCartItems($input: CartItemsAddInput!) {
cart {
...CartFragment
}
errors {
code
message
}
}
`;
const addProductsToCart = (cartId, product) => {
const input = {
id: cartId,
items: {},
};
if (product.marketplace === 'AMAZON') {
input.items.amazonCartItemsInput = [
{ productId: product.id, quantity: 1 },
];
}
if (product.marketplace === 'SHOPIFY') {
input.items.shopifyCartItemsInput = [
{ variantId: product.id, quantity: 1 },
];
}
const variables = { input };
await client.request(
ADD_CART_ITEMS_QUERY,
variables,
headers,
);
}
await addProductsToCart(
// We returned the `cart` object from the `createCartWithProducts` function
// in the previous step.
cart.id,
'B01ANEHLXG',
);
Fetch cart shipping methods and cost
Check if your cart looks good, and fetch the estimated checkout cost and available shipping methods for the cart.
const GET_CART_QUERY = gql`
${CartFragment}
query cart($id: ID!) {
getCart(id: $id) {
...CartFragment
}
}
`;
// Fetch latest cart
const updatedCart = await client.request(GET_CART_QUERY, { id: cart.id }, headers);
// Use `latestCart`
Update buyer identity
Update buyer identity information if it was not provided during cart creation as it is required to be able to submit the cart.
export const UPDATE_CART_BUYER_IDENTITY_QUERY = gql`
${CartFragment}
mutation updateCartBuyerIdentity($input: CartBuyerIdentityUpdateInput!) {
updateCartBuyerIdentity(input: $input) {
cart {
...CartFragment
}
errors {
code
message
}
}
}
`;
const input = {
id: cartId,
buyerIdentity: {
city,
address1,
address2,
firstName,
lastName,
email,
phone,
postalCode,
provinceCode,
countryCode,
},
};
await client.request(
UPDATE_CART_BUYER_IDENTITY_QUERY,
{ input },
headers,
);
Submit your cart
Submit your cart via Rye Pay. For information on setting up a generateJWT
method, see our tutorial.
import { RyePay, SubmitStoreResult, SubmitCartResult } from '@rye-api/rye-pay';
const ryePay = new RyePay();
const loadSpreedly = () => {
ryePay.init({
generateJWT: async () => {
// This should hit an endpoint on your server that generates a JWT for
// use by your frontend application.
},
numberEl: 'spreedly-number',
cvvEl: 'spreedly-cvv',
environment: 'prod',
onCartSubmitted: (result) => {
// Handle errors, or poll `checkoutByCartID` with `submitCartResult.cart.id`
},
onReady: () => {
// Customize card number field and cvv field
ryePay.setStyle(
'number',
'display:inline; width: 30%; border-radius: 3px; border: 1px solid #ccc;',
);
ryePay.setStyle(
'cvv',
'display: inline; width: 30%; border-radius: 3px; border: 1px solid #ccc;',
);
},
onErrors: (errors: SpreedlyError[]) => {
for (const { key, message, attribute } of errors) {
console.log(`new error: ${key}-${message}-${attribute}`);
}
},
enableLogging: true,
onIFrameError: (err: FrameError) => {
console.log(`frameError: ${JSON.stringify(err)}`);
}
});
};
loadSpreedly();
const submit = () => {
ryePay.submit({
cartId: cart.id, // IMPORTANT! Make sure the cartId is valid
selectedShippingOptions: [], // Should come from the cart response
// Read the below from your payment form
first_name: 'John',
last_name: 'Doe',
month: '04',
year: '2025',
address1: 'address1',
address2: 'address2',
zip: 'zip',
city: 'city',
country: 'country',
state: 'state',
});
}
submit();
Display the results of the transaction
After ryePay.submit
submits your cart, it will call your onCartSubmitted
callback with a snapshot of the cart post-checkout. In some cases there may have been some errors during the submission of the cart, and these can be inspected on the result
object.
Errors can occur on the Cart level and the Store level:
- For the cart level:
result.errors
will provide an array of errors related to submitting the cart with appropriate error messages and codes - For the store level:
result.cart.stores[idx].errors
will provide an array of errors related to submitting the order to the store with appropriate error messages and codes
It is important to remember that submitting a cart is an async operation. It is possible for errors to occur after you have submitted the cart. Read more about checkout lifecycle here.
Cart management
- To update the number of existing products in the cart, use the
updateCartItems
mutation. - To remove existing products from the cart, use the
deleteCartItems
mutation. - To remove the entire cart, use the
removeCart
mutation.
Next steps
- We looked at
requestAmazonProductByURL
in this guide, butrequestShopifyProductByURL
andrequestStoreByURL
can also be used to add products to our product data catalog. - Check out our ”starting an integration” guide to get started with building out your real API integration.
- Experiment with our API using one of the following playgrounds:
Before you can make GraphQL requests, you will need to set the correct HTTP headers. Check out our Authorization guide for details.
Was this page helpful?