Loading

Payments · 2026

Subscription Payments Platform

A standalone subscription and payments backend for a Shopify store, covering recurring billing, reconciliation, customer self-service and shipping operations.

Year

2026

Type

Payments

Role

Full Stack Developer

Tech Stack

  • Next.js
  • React
  • JavaScript
  • Prisma
  • PostgreSQL
  • Shopify
  • Tailwind CSS
  • Jest
  • Playwright
  • Sentry
NDAClient work. Source code for this project cannot be shared due to a non-disclosure agreement.

Project Summary

A standalone web application that runs next to a Shopify store and handles recurring subscription billing, customer self-service and the operations work that follows each payment. Customers subscribe or buy once through a custom checkout, then manage delivery day, address, plan, pauses, card and cancellation from a portal embedded in the store theme. Staff use an admin panel to monitor subscriptions and payments, handle refunds and provider-specific manual steps, and plan weekly shipments. Recurring charges run through iyzico and QNB, and one-time orders can also be paid with two meal-card providers.

Most of the engineering goes into keeping local records correct when providers are unreliable. Webhooks are only the fast path: an in-process scheduler reads iyzico and QNB back every 15 minutes under a database lease, and idempotency keys, compare-and-swap updates and a retry queue prevent duplicate payments and Shopify orders. Calendar logic is pinned to the Istanbul day and tested under five process time zones. The repo has 176 API route handlers, 20 Prisma migrations and 169 test files.

Problem & Solution

Problem
  • Dropped or late provider webhooks left subscriptions and shipment rows out of date
  • The QNB API cannot delete recurring instructions, so old or cancelled ones had to be closed by hand in the bank panel
  • iyzico has no native pause, so pausing a subscription meant cancelling it and starting a new one later
  • Dates computed in the server's local time zone shifted delivery-day labels and monthly cadence
  • Repeated callbacks and retries risked duplicate payment records and duplicate Shopify orders
Solution
  • Scheduled reconciliation reads iyzico and QNB back every 15 minutes, with a lease so only one instance runs per cycle
  • A QNB instruction cleanup queue tracks each instruction until a bank inquiry confirms VOID or NOT_FOUND
  • Per-provider pause handling: iyzico hard pause with a resume payment link, QNB manual-action flags, and removal of unlocked shipment rows
  • All scheduling uses Istanbul calendar-day helpers that do not depend on the process time zone
  • Idempotency keys, compare-and-swap sync writes and a Shopify order retry queue with capped attempts

Key Features

01

Multi-provider checkout

Subscription and one-time checkout with iyzico, QNB and two meal-card providers (3D Secure and OTP flows). Each provider can be switched on or off from admin settings.

02

Customer portal

A portal section inside the Shopify theme where customers change delivery day, address and plan, pause, update their card or request cancellation.

03

Shipping operations calendar

A weekly calendar of shipment rows with preparation states, regional overview, per-day stock, courier labels and Excel/PDF exports.

04

Decision center

One queue for cases where money was taken but the shipment is unclear, such as late payments, charges during a pause and cancellation refund reviews.

05

Coupons and stock holds

Percentage and free-shipping coupons with first-order checks through hashed identity locks, plus 30-minute stock reservations per delivery day during checkout.

06

Admin tooling

KPI cards, refunds and provider rollbacks, audit log, system health, webhook replay, and a tool-calling AI assistant (Groq with Gemini fallback) for subscription lookups.

Technical Details

Backend

Next.js App Router with 176 route handlers and Prisma on PostgreSQL, deployed with PM2 behind Caddy. A small Node proxy on a fixed IP forwards calls to bank and courier APIs that only accept whitelisted addresses.

Payments

iyzico subscriptions through the iyzipay SDK; QNB XML gateway for a first direct sale followed by a CPOS recurring instruction; meal-card integrations with 3D Secure, transaction inquiry and signed rollback, and a SOAP flow with RSA-encrypted OTP and HMAC response checks.

Reconciliation

Four jobs (sync-iyzico, sync-qnb, process-deferred-switches, process-subscription-pauses) run in sequence with a 72-hour due lookback, either in-process or through a secret-protected cron endpoint.

Testing

166 Jest test files for libraries and route handlers with TZ pinned to Europe/Istanbul, plus 3 Playwright specs for the admin panel and checkout. Sentry runs with default PII sending turned off.

Have a project? Let's talk.

Have a project in mind or a question about my work? Email or LinkedIn is the best way to reach me.