blocker phase 5
This commit is contained in:
@@ -2,18 +2,12 @@
|
|||||||
* When true, the BNPL domain is served by the in-memory mock (`apis/mockApi.ts`) behind the `BnplApi`
|
* When true, the BNPL domain is served by the in-memory mock (`apis/mockApi.ts`) behind the `BnplApi`
|
||||||
* seam.
|
* seam.
|
||||||
*
|
*
|
||||||
* **Mock is primary this phase.** b12 ships the eligibility/initiate/webhook/settle endpoints server-side,
|
* **Mock is still primary** (blocker-phase 05 landed Bug A — the seeded BNPL gateway — but not Bug B):
|
||||||
* but the D1–D5 checkout cannot run real end-to-end from the client yet:
|
* the D1 wizard hard-gates on `getBnplOptions` (`GET checkout_bnpl/options/{id}`), and `getBnplSchedule` /
|
||||||
* - the accepted request being financed comes from the **mock-primary** `bookingRequests` store (f7), so a
|
* `getWalletInstallments` have no server counterpart either — `CheckoutBnplController` only ever grew
|
||||||
* real `initiate` would reference an id that exists only in memory (same reason f9 payment is mock-primary);
|
* `eligibility` / `initiate` / `GET {id}` / `by_request/{id}` (REQ-022/023/024 never landed). Flipping this
|
||||||
* - the contract serves **no provider/plan options** (D1/D2), **no repayment schedule** (D4 — the contract
|
* flag today trades the old "mock store ages out" failure for an immediate `isError` on D1. Flip once those
|
||||||
* explicitly does not model the customer's repayment schedule), and **no provider-reported installment
|
* three endpoints exist server-side — no hook/component change needed at that point.
|
||||||
* status** for the Wallet (D5) → REQ-022/023/024;
|
|
||||||
* - nothing fires the provider webhook in dev, so a real order would never settle.
|
|
||||||
* The mock closes the loop: the settle (down-payment cleared) converts the f7 request, inserts a **confirmed**
|
|
||||||
* booking into the f8 store (the SAME bridge f9 uses — a settled BNPL order is a card payment net-of-fee),
|
|
||||||
* and seeds a Wallet installment plan — so C6 → D1 → … → D4 → confirmation → D5 demos end-to-end. Flip to
|
|
||||||
* `false` once the upstream domains are real and REQ-022/023/024 land — no hook/component change.
|
|
||||||
*/
|
*/
|
||||||
export const USE_BNPL_MOCK = true;
|
export const USE_BNPL_MOCK = true;
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -21,8 +21,13 @@ Effort is a rough size, not a schedule: **S** = small/contained, **M** = a real
|
|||||||
- **The 30-minute payment countdown can lie.** Booking deadlines are stored without a timezone, so the timer
|
- **The 30-minute payment countdown can lie.** Booking deadlines are stored without a timezone, so the timer
|
||||||
a customer sees can silently show hours more time than they actually have, and expire while they still
|
a customer sees can silently show hours more time than they actually have, and expire while they still
|
||||||
think they're fine. *(Effort: S)*
|
think they're fine. *(Effort: S)*
|
||||||
- **Installment (buy-now-pay-later) payments don't work at all.** No installment plan is ever actually set up
|
- **Installment (buy-now-pay-later) payments don't work at all.** The behind-the-scenes setup that lets an
|
||||||
behind the scenes, so every attempt fails immediately. *(Effort: S–M, two related issues)*
|
installment plan get created at all is now fixed — but the on-screen wizard still can't be turned on to use
|
||||||
|
it: three of its screens (choosing a plan, seeing the repayment schedule, and the "my installments" wallet
|
||||||
|
view) call server endpoints that were never actually built, so switching off the fake demo data today would
|
||||||
|
make the first screen show an error immediately instead of the outdated-mock failure it shows now. Those
|
||||||
|
three endpoints need to be built before this can be turned on for real. *(Effort: S–M, one part fixed, one
|
||||||
|
part bigger than first scoped)*
|
||||||
- **Refunds are demo-only today.** The refund screens read fake, disconnected sample data; turning that off
|
- **Refunds are demo-only today.** The refund screens read fake, disconnected sample data; turning that off
|
||||||
today would show a refund of the wrong amount (off by a factor of 100) for any real cancellation.
|
today would show a refund of the wrong amount (off by a factor of 100) for any real cancellation.
|
||||||
*(Effort: M)*
|
*(Effort: M)*
|
||||||
|
|||||||
+31
-14
@@ -8,6 +8,7 @@ using Baya.Application.Contracts.Payments;
|
|||||||
using Baya.Application.Contracts.Persistence;
|
using Baya.Application.Contracts.Persistence;
|
||||||
using Baya.Application.Contracts.Search;
|
using Baya.Application.Contracts.Search;
|
||||||
using Baya.Application.Contracts.SupportAlerts;
|
using Baya.Application.Contracts.SupportAlerts;
|
||||||
|
using Baya.Domain.Entities.Bnpl;
|
||||||
using Baya.Domain.Entities.Payments;
|
using Baya.Domain.Entities.Payments;
|
||||||
using Baya.Infrastructure.Persistence.Interceptors;
|
using Baya.Infrastructure.Persistence.Interceptors;
|
||||||
using Baya.Infrastructure.Persistence.Repositories.Common;
|
using Baya.Infrastructure.Persistence.Repositories.Common;
|
||||||
@@ -128,27 +129,43 @@ public static class ServiceCollectionExtensions
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Idempotently seeds one active <c>standard</c> payment gateway so the b10 card rail has a selectable
|
/// Idempotently seeds one active <c>standard</c> payment gateway so the b10 card rail has a selectable
|
||||||
/// provider out of the box. <c>config_json</c> is encrypted at rest by the EF converter on save (so it
|
/// provider out of the box, plus one active <c>bnpl</c> gateway (<c>balinyaar</c>, the in-house
|
||||||
/// must go through the DbContext, not <c>HasData</c>). Real merchant credentials come from appsettings /
|
/// net-of-fee provider per money.md §6 — needs no external credentials) so b12's eligibility/initiate
|
||||||
/// environment per deployment — this sandbox row is non-secret and only enables the local/dev flow.
|
/// handlers have a gateway to select instead of short-circuiting. <c>config_json</c> is encrypted at rest
|
||||||
|
/// by the EF converter on save (so it must go through the DbContext, not <c>HasData</c>). Real merchant
|
||||||
|
/// credentials come from appsettings / environment per deployment — these sandbox rows are non-secret and
|
||||||
|
/// only enable the local/dev flow.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static async Task SeedPaymentGatewaysAsync(this WebApplication app)
|
public static async Task SeedPaymentGatewaysAsync(this WebApplication app)
|
||||||
{
|
{
|
||||||
await using var scope = app.Services.CreateAsyncScope();
|
await using var scope = app.Services.CreateAsyncScope();
|
||||||
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||||
|
|
||||||
if (await context.Set<PaymentGateway>().AnyAsync(g => g.Type == PaymentGatewayType.Standard))
|
if (!await context.Set<PaymentGateway>().AnyAsync(g => g.Type == PaymentGatewayType.Standard))
|
||||||
return;
|
|
||||||
|
|
||||||
context.Set<PaymentGateway>().Add(new PaymentGateway
|
|
||||||
{
|
{
|
||||||
ProviderCode = "zarinpal",
|
context.Set<PaymentGateway>().Add(new PaymentGateway
|
||||||
Type = PaymentGatewayType.Standard,
|
{
|
||||||
DisplayName = "ZarinPal (sandbox)",
|
ProviderCode = "zarinpal",
|
||||||
ConfigJson = "{\"merchantId\":\"00000000-0000-0000-0000-000000000000\",\"baseUrl\":\"https://sandbox.zarinpal.com\",\"sandbox\":true}",
|
Type = PaymentGatewayType.Standard,
|
||||||
IsActive = true,
|
DisplayName = "ZarinPal (sandbox)",
|
||||||
Priority = 0
|
ConfigJson = "{\"merchantId\":\"00000000-0000-0000-0000-000000000000\",\"baseUrl\":\"https://sandbox.zarinpal.com\",\"sandbox\":true}",
|
||||||
});
|
IsActive = true,
|
||||||
|
Priority = 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await context.Set<PaymentGateway>().AnyAsync(g => g.Type == PaymentGatewayType.Bnpl))
|
||||||
|
{
|
||||||
|
context.Set<PaymentGateway>().Add(new PaymentGateway
|
||||||
|
{
|
||||||
|
ProviderCode = BnplProviderCodes.Balinyaar,
|
||||||
|
Type = PaymentGatewayType.Bnpl,
|
||||||
|
DisplayName = "Balinyaar BNPL",
|
||||||
|
ConfigJson = "{\"sandbox\":true}",
|
||||||
|
IsActive = true,
|
||||||
|
Priority = 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user