পাঠ্যক্রম খুলুন
অগ্রসর পর্যায়

Payment System: পূর্ণ মক ইন্টারভিউ

Mock Interview: Payment System

এই পাঠের কুইজ ↓৭ মিনিট পড়াPHP 8.3+ · Laravel 12
এই পাঠের সূচিপত্র

এই পাঠে যা শিখবেন

  • পূর্ণ payment mock-এ uncertain outcome reasoning
  • Idempotency ও double-entry posting boundary নির্ধারণ
  • Reconciliation এবং operational safety defend করা

সমস্যা দিয়ে শুরু

Interviewer: payment service design করুন। Candidate: merchant checkout payment initiation, status, provider webhook, refund এবং settlement reconciliation scope নিচ্ছি। Card processing network নিজে বানাচ্ছি না, hosted/tokenized provider integration ধরছি। Primary invariant একই order operation ভুল করে double capture না করা এবং local financial record auditable রাখা। Network exactly-once নয়; unknown outcome system state হিসেবে থাকবে। Interviewer বলেন timeout ও duplicate webhook নিয়ে deep dive করুন।

সহজ করে বুঝি

Candidate response: POST /orders/{id}/payment-attempts stable operation key, amount ও currency server-owned order থেকে নেবে। GET /payment-attempts/{id} owner-only। POST /webhooks/provider provider-specific signature যাচাই করবে, event durable লিখে দ্রুত acknowledgment দেবে। Tables: attempts(operation_key unique,order_id,provider_ref,status), provider_events(event_id unique,payload_ref), journals(business_reference unique), entries(journal_id,account_id,direction,amount_minor,currency)। একই currency journal-এ debit=credit invariant enforce করতে হবে।

পরিচিত একটি উপমা

এক transfer-এর reference নিয়ে bank-এ ফল জানতে যাওয়া reconciliation। Receipt হারালেই আবার transfer নয়। Accounting register-এ balance-এর বিপরীত দুই side নথিবদ্ধ হয়; refund নতুন transaction, পুরোনো ইতিহাস ঘষে মুছে দেওয়া নয়।

নকশাটি দেখুন

Diagram লোড হচ্ছে…

পূর্ণ payment mock unknown outcome স্বীকার করে এবং provider identity, local transition ও balanced ledger-এর আলাদা correctness boundary রক্ষা করে।
Diagram-এর text flow দেখুন
flowchart TD
 U[Owner payment request] --> A[Persist stable attempt]
 A --> P[Provider idempotent request]
 P -->|No response| X[Unknown state]
 P --> W[Signed webhook receipt]
 W --> E[(Unique received events)]
 E --> T[Conditional local transition]
 X --> R[Reconciliation query]
 R --> T
 T --> L[(Balanced ledger and outbox)]

Candidate: local attempt durable করার পরে provider call করব, DB lock ধরে network wait নয়। Timeout হলে failed না লিখে unknown/reconciliation-required রাখব। Webhook raw payload signature verify করে unique event receipt লিখবে। Worker attempt current state দেখে transition করবে এবং journal/outbox একই local transaction-এ। Event ordering unknown; stale event যাতে succeeded state পিছিয়ে না দেয় conditional transition বা provider current state query লাগবে।

PHP ও Laravel-এ প্রয়োগ

Estimate assumption: দিনে ১০ লাখ payment attempt হলে average প্রায় ১২ initiation/second; peak, webhook, status poll ও retry বাড়বে। প্রতিটি payment বহু ledger row করে, তাই attempt QPS ledger write count নয়। Financial retention years হলে storage ও privacy/compliance policy আলাদা expert review লাগে; এখানে certification দাবি নেই। নিচের Laravel fragment local succeeded transition-এর simplified অংশ; signature, amount/currency, provider reference verified এবং journal posting helper implementation reviewed বলে ধরে নেওয়া।

php
use App\Models\PaymentAttempt;
use Illuminate\Support\Facades\DB;
DB::transaction(function () use ($attemptId, $verifiedResult) {
    $attempt = PaymentAttempt::query()->lockForUpdate()->findOrFail($attemptId);
    if ($attempt->status === 'succeeded') {
        return;
    }
    abort_unless($verifiedResult->amountMinor === $attempt->amount_minor, 409);
    abort_unless($verifiedResult->currency === $attempt->currency, 409);
    $this->ledger->postBalancedPayment($attempt);
    $attempt->update(['status' => 'succeeded']);
});

সুবিধা, সীমাবদ্ধতা ও trade-off

Interviewer: idempotency থাকলেই সব solved? Candidate: না। Provider key retention, same payload rules এবং scope contract সীমিত। Local unique operation key, provider request identity এবং ledger business_reference আলাদা boundary। Event receipt dedupe business state transition-এর equivalent নয়। Synchronous response fast confirmation দিতে পারে; final async status handling তবু দরকার। Hosted payment integration sensitive-data exposure কমাতে সাহায্য করে, সম্পূর্ণ compliance guarantee নয়।

সাধারণ ভুল

  • Timeout-এর পরে নতুন operation key দিয়ে blind charge করা।
  • Webhook event ID unique হলেই ledger posting unique ভাবা।
  • Money float এবং currency ছাড়া store করা।

আরও একটু গভীরে

Candidate deep dive: provider charge succeeded, local process মারা গেল। Reconciliation worker pending/unknown attempts query করে provider reference বা stable operation identity দিয়ে result আনে। Settlement report reconciliation amount, currency, fee ও net mismatch ধরতে পারে। Refund state আলাদা provider operation ও balanced compensating journal লিখবে। Incorrect old event confirmed success rollback করবে না; dispute/chargeback আলাদা domain event হতে পারে। Security-তে webhook signing secret rotation, replay window contract, least privilege, access audit ও sensitive payload redaction দরকার। Observability-তে unknown-state age, reconciliation backlog, unbalanced posting rejection এবং provider error ratio রাখব। Recovery drill backup restore-এর পরে duplicate event replay করেও ledger invariant বজায় আছে দেখাবে। Final limitation: one provider abstraction দিয়ে provider-specific semantics মুছে যাবে না; contract adapters এবং integration sandbox tests লাগবে।

মনে রাখুন

পূর্ণ payment mock unknown outcome স্বীকার করে এবং provider identity, local transition ও balanced ledger-এর আলাদা correctness boundary রক্ষা করে।

নিজে চেষ্টা করুন

এই response নিয়ে তিন failure walk-through করুন: successful charge/response loss, duplicate event এবং refund callback before local response। প্রতিটিতে durable record, next action, dedupe boundary এবং user-visible state লিখুন। Fake provider test ও real sandbox integration কী আলাদা প্রমাণ করে বলুন।

নিজের বোঝা যাচাই করুন

1. Unknown কেন failed নয়?

Caller response পাননি মানে provider operation হয়নি নয়। ভুল failure retry duplicate charge ঘটাতে পারে।

2. Event dedupe যথেষ্ট?

এক business payment-এর বহু event হতে পারে। State transition এবং ledger reference-এর আলাদা idempotency দরকার।

3. Ledger helper কী enforce করবে?

Balanced entries, exact amount/currency এবং unique business posting একই local transaction-এ। Snippet সেই full implementation দেয় না।

4. Refund original delete?

না। Compensating financial event historical audit রাখে। Provider refund-এর outcome-ও asynchronous হতে পারে।

5. Reconciliation optional?

Unknown বা silently missed outcome recover করার fundamental path। Stable reference, backlog monitoring ও operator tooling দরকার।

আরও পড়ুন

এই পাঠের কুইজ

এই পাঠ থেকে ২টি প্রশ্ন। উত্তর দিয়ে ব্যাখ্যা দেখুন; অধ্যায়ের কুইজ আলাদাভাবে দিতে হবে।

এই পাঠের ২টি প্রশ্নের উত্তর দিন। পাস করতে দুটিই সঠিক হতে হবে।

জমা দেওয়ার পর সঠিক উত্তর ও ব্যাখ্যা দেখবেন। ফলাফল এই ব্রাউজারে সংরক্ষিত থাকবে। অনুশীলনের ফল অধ্যায় সম্পন্নের হিসাবে যোগ হয় না।

সব বিষয় মিলিয়ে অনুশীলন করুন →

অগ্রগতি এই ব্রাউজারে সংরক্ষিত থাকে। শুধু পাঠ খুললে সম্পন্ন হয় না।