Customer API

Documentation for the Submarine Customer API.

The Customer API is used to build bespoke interfaces to allow customers to manage their stored payment methods and subscriptions.

It's designed to be called from within the context of a customer logged in to their Shopify account, either from a browser or other client (such as a mobile app).

The API follows the JSON API Specification, and provide endpoints for retrieving, creating and updating stored payment methods, subscriptions, and individual subscription orders.

A Javascript client library (Submarine.js) is provided by Disco Labs to simplify interaction with the Customer API. This library can be imported into an existing theme development workflow, or included via a <script> tag.

Instructions and code examples for using the Submarine.js client library are available on Github.

Authentication

Because the API is returning sensitive customer information (a list of their stored payment methods, saved subscriptions, and the contents of those subscriptions), authentication in required to retrieve or update any customer information.

Requests to the API are authenticated by providing three parameters in the querystring of all HTTP requests:

  • shop - the Shopify domain of the current store, eg example.myshopify.com;

  • timestamp - a UNIX timestamp of when the request was generated;

  • signature - a SHA256 HMAC signature generated from the ID of the logged in customer, the timestamp value, and a secret key made available to your theme via a shop-level metafield shop.metafields.submarine.customer_api_secret.

For Shopify themes, these values should be generated within your Liquid templates and passed to the Javascript code that will be making calls to the Customer API.

For other clients, such as mobile apps, these values should be generated within your application code before making calls.

Example generation

accounts.liquid
{% assign api_timestamp = 'now' | date: '%s' %}
{% assign api_data = customer.id | append: ':' | append: api_timestamp %}
{% assign api_signature = api_data | hmac_sha256: shop.metafields.submarine.customer_api_secret %}
<script>
window.submarine = new Submarine({
environment: "production",
authentication: {
shop: "{{ shop.permanent_domain }}",
timestamp: "{{ api_timestamp }}",
signature: "{{ api_signature }}"
}
});
</script>

Example request

An example authenticated API request to fetch the list of payment methods for the current customer (with an ID of 82500043234) may therefore look like the following:

GET https://submarine.discolabs.com/api/v1/customers/82500043234/payment_methods?shop=example.myshopify.com&timestamp=1556957501&signature=4400f4c50dc953d000a735beb5becd6460141980d3d0d5a207b47ec6b3124f5e

For brevity, we omit these authentication parameters from the endpoint documentation below, but note that they are required for all requests.

Payment method endpoints

get
List payment methods

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/payment_methods.json
Fetch a list of the current customer's active payment methods.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
Response
200: OK
Successfully retrieved a list of payment methods.
{
"data": [
{
"id": "75199384",
"type": "customer_payment_method",
"attributes": {
"status": "active",
"payment_data": {
"brand": "Visa",
"last4": "4242",
"exp_year": 2022,
"exp_month": 1,
"processor": "stripe"
},
"payment_method_type": "credit-card",
"authorized_payment_method_id": 825022
}
},
{
"id": "75199212",
"type": "customer_payment_method",
"attributes": {
"status": "active",
"payment_data": {
"email": "customer@example.com",
"processor": "braintree"
},
"payment_method_type": "paypal",
"authorized_payment_method_id": 221099
}
}
]
}

post
Create new payment method

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/payment_methods.json
Create a new payment method for the current customer. Body parameters should be passed as a JSON object wrapped in a payment_method namespace.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
Body Parameters
payment_token
required
string
A payment token retrieved from a payment processor's JS SDK.
payment_method_type
required
string
The type of payment method. One of credit-card, paypal or sepa.
payment_processor
required
string
The payment processor. Either stripe or braintree.
status
required
string
Status of the new method. Should be active.
Response
200: OK
{
"data": {
"id": "5208432",
"type": "customer_payment_method",
"attributes": {
"status": "active",
"payment_data": {
"brand": "Visa",
"last4": "4242",
"exp_month": 1,
"exp_year": 2022,
"processor": "stripe"
},
"payment_method_type": "credit-card",
"authorized_payment_method_id": 9012424
}
}
}

delete
Remove existing payment method

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/payment_methods/{{ id }}.json
Remove (disable) an existing payment method belonging to the current customer.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
id
required
integer
ID of the payment method to remove.
Response
200: OK
{
"data": {
"id": "5208432",
"type": "customer_payment_method",
"attributes": {
"status": "disabled",
"payment_data": {
"brand": "Visa",
"last4": "1111",
"exp_year": 2020,
"exp_month": 1,
"processor": "stripe"
},
"payment_method_type": "credit-card",
"authorized_payment_method_id": 9012424
}
}
}

Subscription endpoints

get
List subscriptions

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/subscriptions.json
Fetch a list of the current customer's active subscriptions
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
Response
200: OK
{
"data": [
{
"id": "63594867",
"type": "subscription",
"attributes": {
"status": "active",
"created_at": "2019-05-01T05:14:27.441Z",
"cancelled_at": null,
"paused_at": null,
"note": "",
"customer_name": "Jane Doe",
"customer_email": "jane@example.com",
"billing_address": {
"zip": "3000",
"city": "Melbourne",
"name": "Jane Doe",
"phone": null,
"company": null,
"country": "Australia",
"address1": "100 Main Street",
"address2": "",
"latitude": null,
"province": "Victoria",
"last_name": "Doe",
"longitude": null,
"first_name": "Jane",
"country_code": "AU",
"province_code": "VIC"
},
"frequency": "42_days",
"frequency_human": "Every 6 weeks",
"line_items": {
"data": [
{
"id": "40850",
"type": "subscription_line_item",
"attributes": {
"product_id": 1506703278149,
"variant_id": 13587185303621,
"quantity": 5,
"price": "8.90",
"properties": null,
"title": "Beauty Berry Porridge"
}
},
{
"id": "40851",
"type": "subscription_line_item",
"attributes": {
"product_id": 1506738864197,
"variant_id": 13587544539205,
"quantity": 1,
"price": "15.90",
"properties": [
{
"name": "_applied_subscription_discount",
"value": "135"
}
],
"title": "Kids Blendies"
}
}
]
},
"shipping_method": {
"data": {
"id": "84573",
"type": "subscription_shipping_method",
"attributes": {
"note": null,
"shipping_rates": [
{
"id": 851467108421,
"code": "Standard Shipping (3-6 days)",
"phone": null,
"price": "0.00",
"title": "Standard Shipping (3-6 days)",
"source": "shopify",
"discounted_price": "0.00"
}
],
"shipping_address": {
"first_name": "Jane",
"last_name": "Doe",
"address1": "100 Main Street",
"address2": "",
"city": "Melbourne",
"zip": "3000",
"province": "Victoria",
"province_code": "VIC",
"country": "Australia"
}
}
}
},
"payment_method": {
"data": {
"id": "349580",
"type": "customer_payment_method",
"attributes": {
"status": "active",
"payment_data": {
"brand": "Visa",
"last4": "4242",
"exp_year": 2024,
"exp_month": 4,
"processor": "stripe"
},
"payment_method_type": "credit-card",
"authorized_payment_method_id": 235252
}
}
},
"next_scheduled_order": {
"data": {
"id": "12521",
"type": "subscription_order",
"attributes": {
"status": "scheduled",
"shipping_rate": {},
"scheduled_at": "2019-05-18T00:00:00.000Z",
"processed_at": null,
"skipped_at": null,
"cancelled_at": null,
"order_id": null,
"sequential_id": 2,
"shopify_url": "#",
"order_line_items": {
"data": [
{
"id": "35625",
"type": "subscription_order_line_item",
"attributes": {
"subscription_order_id": 12521,
"product_id": 1506703278149,
"variant_id": 13587185303621,
"quantity": 5,
"price": "8.90",
"properties": []
}
},
{
"id": "35624",
"type": "subscription_order_line_item",
"attributes": {
"subscription_order_id": 12521,
"product_id": 1506738864197,
"variant_id": 13587544539205,
"quantity": 1,
"price": "15.90",
"properties": [
{
"name": "_applied_subscription_discount",
"value": "135"
}
]
}
}
]
}
}
}
}
}
}
]
}

patch
Update existing subscription

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/subscriptions/{{ id }}.json
Update an existing subscription belonging to the current customer.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
id
required
integer
ID of the subscription to update.
Response
200: OK

delete
Delete existing subscription

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/subscriptions/{{ id }}.json
Remove an existing subscription belonging to the current customer.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
id
required
integer
ID of the subscription to remove.
Response
200: OK

Subscription order endpoints

get
List subscription orders

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/subscriptions/{{ subscription_id }}/subscription_orders.json
Fetch a list of the subscription orders for the given subscription.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
subscription_id
required
integer
ID of the subscription to retrieve orders for.
Response
200: OK

patch
Update existing subscription order

https://submarine.discolabs.com/api/v1/customers/{{ customer_id }}/subscriptions/{{ subscription_id }}/subscription_orders/{{ id }}.json
Update an existing subscription order.
Request
Response
Request
Path Parameters
customer_id
required
integer
ID of the currently logged in customer.
subscription_id
required
integer
ID of the subscription the subscription order to be updated belongs to.
id
required
integer
ID of the subscription order to update.
Response
200: OK