Shopify Integration
Manza doesn't yet ship a native Shopify Payments app. In the meantime, several merchants run Manza alongside Shopify using the patterns below.
What works today#
You can accept card payments for Shopify orders, with one constraint: the buyer leaves the Shopify checkout page to pay on a Manza-hosted page. Once payment completes, you reconcile the Shopify order with a webhook.
- Checkout Sessions API — server-created, one-off, expire in 30 minutes by default. Best fit for cart checkout.
- Payment Links API — single-use or reusable URLs you email or SMS to a buyer. Best fit for manual invoicing.
- Webhooks — checkout_session.completed and payment_link.paid events for reconciliation.
Which pattern fits you?#
- Pattern A — Post-purchase redirect. In-house engineering; cleanest buyer experience without a Payments App. A custom Shopify app subscribes to orders/create, calls POST /api/checkout_sessions server-side, then sends the buyer the returned url (email/SMS, or a Plus post-purchase checkout extension).
- Pattern B — Workflow automation (no-code). Trigger on Shopify's orders/create in n8n/Zapier/Make, create a checkout session, email/SMS the url, mark the order paid on checkout_session.completed. Simpler to build; higher abandonment than A.
- Pattern C — Standalone Payment Links. Direct sales (Instagram/WhatsApp/in-person) with Shopify as catalog only. Create a payment link per product and send it through your usual channels.
Example: create a checkout session from your Shopify app#
POST /api/checkout_sessions
The metadata.shopify_order_id is echoed back in the checkout_session.completed webhook — use it to look up the Shopify order and mark it paid via the Shopify Admin API. completed fires the moment the buyer's payment is confirmed (the session then reads clearing until the provider settles); wait for checkout_session.settled instead only if your flow must not run before funds have actually landed.
curl -X POST "https://ma.manza.dev/api/checkout_sessions" \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"account_id": "01964a3b-0000-7000-8000-ac6000000a01",
"amount": 1500.00,
"success_url": "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
"cancel_url": "https://your-shop.myshopify.com/cart",
"metadata": { "shopify_order_id": "5142318973029" },
"description": "Order #1042"
}'manza checkout-sessions create \
--account-id 01964a3b-0000-7000-8000-ac6000000a01 \
--amount 1500.00 \
--success-url "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}" \
--cancel-url "https://your-shop.myshopify.com/cart"import { Manza } from "@getmanza/sdk";
const manza = new Manza({ apiKey: process.env.MANZA_API_KEY });
await manza.checkoutSessions.create({
account_id: "01964a3b-0000-7000-8000-ac6000000a01",
amount: "1500.00",
success_url: "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
cancel_url: "https://your-shop.myshopify.com/cart",
metadata: { shopify_order_id: "5142318973029" },
});require "manza"
manza = Manza.new(api_key: ENV["MANZA_API_KEY"])
manza.checkout_sessions.create(
account_id: "01964a3b-0000-7000-8000-ac6000000a01",
amount: "1500.00",
success_url: "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
cancel_url: "https://your-shop.myshopify.com/cart",
metadata: { shopify_order_id: "5142318973029" }
)from manza import Manza
client = Manza() # reads MANZA_API_KEY
client.checkout_sessions.create(
account_id="01964a3b-0000-7000-8000-ac6000000a01",
amount="1500.00",
success_url="https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
cancel_url="https://your-shop.myshopify.com/cart",
metadata={"shopify_order_id": "5142318973029"},
)import manza "github.com/getmanza/manza-go"
client, _ := manza.New(manza.WithAPIKey(os.Getenv("MANZA_API_KEY")))
session, err := client.CheckoutSessions.Create(ctx, manza.Attributes{
"account_id": "01964a3b-0000-7000-8000-ac6000000a01",
"amount": "1500.00",
"success_url": "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
"cancel_url": "https://your-shop.myshopify.com/cart",
"metadata": map[string]any{"shopify_order_id": "5142318973029"},
})let client = manza::Client::builder()
.api_key(std::env::var("MANZA_API_KEY")?)
.build()?;
let session = client.checkout_sessions().create(&serde_json::json!({
"account_id": "01964a3b-0000-7000-8000-ac6000000a01",
"amount": "1500.00",
"success_url": "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
"cancel_url": "https://your-shop.myshopify.com/cart",
"metadata": { "shopify_order_id": "5142318973029" },
}))?;{:ok, client} = Manza.new(api_key: System.fetch_env!("MANZA_API_KEY"))
{:ok, session} =
Manza.CheckoutSessions.create(client, %{
"account_id" => "01964a3b-0000-7000-8000-ac6000000a01",
"amount" => "1500.00",
"success_url" => "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
"cancel_url" => "https://your-shop.myshopify.com/cart",
"metadata" => %{"shopify_order_id" => "5142318973029"}
})require "manza"
client = Manza::Client.new # reads MANZA_API_KEY
session = client.checkout_sessions.create(
account_id: "01964a3b-0000-7000-8000-ac6000000a01",
amount: "1500.00",
success_url: "https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}",
cancel_url: "https://your-shop.myshopify.com/cart",
metadata: {shopify_order_id: "5142318973029"}
)use Manza\Client;
$client = new Client(apiKey: getenv('MANZA_API_KEY'));
$session = $client->checkoutSessions->create([
'account_id' => '01964a3b-0000-7000-8000-ac6000000a01',
'amount' => '1500.00',
'success_url' => 'https://your-shop.myshopify.com/account/orders?session={CHECKOUT_SESSION_ID}',
'cancel_url' => 'https://your-shop.myshopify.com/cart',
'metadata' => ['shopify_order_id' => '5142318973029'],
]);Reconciliation#
- Verify the webhook signature using the X-Manza-Signature header.
- Look up the Shopify order via metadata.shopify_order_id (A/B) or payment_reference (C).
- Mark the order paid via the Shopify Admin API (orderMarkAsPaid mutation). checkout_session.completed is the payment confirmation — the session may still read clearing (settled_at null) until the provider settles and checkout_session.settled fires.
- Return 2xx within 10 seconds; Manza retries non-2xx on the standard schedule.
Refunds: Manza settles card payments directly into your bank account, so refunds aren't issued by Manza or visible from the Shopify admin — you issue them from your bank.
FAQ#
Why is there no Manza app in the Shopify App Store?
Manza currently provides an API integration, not a published Shopify Payments app. The patterns above require your own integration or workflow automation.
Can customers select Manza inside Shopify checkout?
The integration described here takes the buyer to a Manza-hosted payment page. It does not install a native Manza payment option alongside Shopify's payment providers.
Does this support Shopify subscriptions or recurring orders?
These flows do not automatically charge a saved card or manage Shopify subscription contracts. Your integration must schedule a new payment request each billing period, ask the customer to pay, and reconcile the payment with the corresponding order.
Follow the Recurring billing guide for billing cycles and webhook confirmation.
What happens to refunds initiated in Shopify?
A Shopify refund does not trigger a refund through this Manza integration. Follow the refund process described under Reconciliation and update your Shopify records to match; do not assume the two systems synchronize refunds automatically.