@mohasinac/appkit 4.41.17 → 4.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_internal/client/features/maintenance/views/MaintenanceDashboardView.js +1 -1
- package/dist/_internal/server/features/checkout/actions.d.ts +16 -14
- package/dist/_internal/server/features/checkout/actions.js +145 -97
- package/dist/_internal/server/features/checkout/bundle-expansion.d.ts +1 -1
- package/dist/_internal/server/features/checkout/index.d.ts +1 -1
- package/dist/_internal/server/features/checkout/index.js +1 -1
- package/dist/_internal/server/features/checkout/locked-lines.js +1 -1
- package/dist/_internal/server/features/checkout/source-context.js +2 -2
- package/dist/_internal/server/features/maintenance/analyze.js +1 -1
- package/dist/_internal/server/features/refunds/actions.d.ts +4 -4
- package/dist/_internal/server/features/refunds/actions.js +9 -8
- package/dist/_internal/server/functions/scheduled.d.ts +1 -2
- package/dist/_internal/server/functions/scheduled.js +1 -9
- package/dist/_internal/server/jobs/core/index.d.ts +0 -1
- package/dist/_internal/server/jobs/core/index.js +0 -1
- package/dist/_internal/server/jobs/handlers/index.d.ts +0 -1
- package/dist/_internal/server/jobs/handlers/index.js +0 -1
- package/dist/_internal/shared/actions/action-registry.js +2 -2
- package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
- package/dist/_internal/shared/checkout/order-math.js +1 -1
- package/dist/_internal/shared/checkout/rules/prize-draw.rule.js +2 -2
- package/dist/_internal/shared/features/blog/schema.d.ts +4 -4
- package/dist/_internal/shared/features/cart/schema.d.ts +6 -6
- package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
- package/dist/_internal/shared/features/orders/refund-copy.js +1 -1
- package/dist/_internal/shared/features/orders/schema.d.ts +5 -5
- package/dist/_internal/shared/features/orders/schema.js +1 -1
- package/dist/_internal/shared/features/products/schema.d.ts +2 -2
- package/dist/_internal/shared/features/promotions/schema.d.ts +4 -4
- package/dist/_internal/shared/features/reviews/schema.d.ts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/configs/next.js +2 -2
- package/dist/constants/field-names.d.ts +1 -1
- package/dist/constants/field-names.js +1 -1
- package/dist/contracts/index.d.ts +0 -2
- package/dist/contracts/index.js +0 -1
- package/dist/contracts/payment.d.ts +13 -2
- package/dist/contracts/payment.js +2 -2
- package/dist/core/integration-keys.d.ts +7 -3
- package/dist/core/integration-keys.js +13 -7
- package/dist/core/money.d.ts +11 -0
- package/dist/core/money.js +15 -0
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/messages.d.ts +1 -0
- package/dist/errors/messages.js +1 -0
- package/dist/errors/{razorpay-unreachable.d.ts → payment-provider-unreachable.d.ts} +1 -1
- package/dist/errors/{razorpay-unreachable.js → payment-provider-unreachable.js} +1 -1
- package/dist/features/addresses/schemas/address-form.d.ts +20 -20
- package/dist/features/addresses/schemas/index.d.ts +2 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +32 -16
- package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
- package/dist/features/admin/schemas/admin-ops-forms.d.ts +10 -10
- package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
- package/dist/features/admin/schemas/firestore.d.ts +17 -8
- package/dist/features/admin/schemas/firestore.js +1 -1
- package/dist/features/admin/schemas/nav-item-form.d.ts +2 -2
- package/dist/features/auctions/schemas/index.d.ts +2 -2
- package/dist/features/auth/schemas/index.d.ts +2 -2
- package/dist/features/before-after/schemas/index.d.ts +2 -2
- package/dist/features/blog/actions/blog-actions.d.ts +4 -4
- package/dist/features/blog/schemas/blog-form.d.ts +2 -2
- package/dist/features/blog/schemas/index.d.ts +4 -4
- package/dist/features/cart/schemas/index.d.ts +3 -3
- package/dist/features/catalogue/schemas/validation.d.ts +4 -4
- package/dist/features/categories/schemas/index.d.ts +2 -2
- package/dist/features/checkout/index.d.ts +0 -4
- package/dist/features/checkout/index.js +0 -3
- package/dist/features/checkout/types/index.d.ts +0 -25
- package/dist/features/checkout/types/index.js +1 -2
- package/dist/features/collections/schemas/index.d.ts +2 -2
- package/dist/features/consultation/schemas/index.d.ts +4 -4
- package/dist/features/corporate/schemas/index.d.ts +2 -2
- package/dist/features/events/schemas/index.d.ts +4 -4
- package/dist/features/grouped/schemas/index.d.ts +2 -2
- package/dist/features/homepage/schemas/index.d.ts +2 -2
- package/dist/features/lottery/schemas/zod.d.ts +4 -4
- package/dist/features/loyalty/schemas/index.d.ts +6 -6
- package/dist/features/orders/components/OrderPaymentSummary.d.ts +1 -1
- package/dist/features/orders/components/OrderPaymentSummary.js +5 -5
- package/dist/features/orders/components/RefundHistoryTable.js +1 -1
- package/dist/features/orders/repository/orders.repository.d.ts +10 -1
- package/dist/features/orders/repository/orders.repository.js +17 -1
- package/dist/features/orders/schemas/firestore.d.ts +11 -12
- package/dist/features/orders/schemas/firestore.js +0 -1
- package/dist/features/orders/schemas/index.d.ts +48 -48
- package/dist/features/orders/schemas/index.js +1 -1
- package/dist/features/orders/types/index.d.ts +1 -3
- package/dist/features/orders/types/index.js +1 -2
- package/dist/features/payments/manifest.js +1 -1
- package/dist/features/payments/repository/payout.repository.d.ts +1 -4
- package/dist/features/payments/repository/payout.repository.js +0 -29
- package/dist/features/payments/schemas/firestore.d.ts +8 -15
- package/dist/features/payments/schemas/firestore.js +7 -5
- package/dist/features/payments/schemas/index.d.ts +52 -125
- package/dist/features/payments/schemas/index.js +0 -58
- package/dist/features/payments/types/index.d.ts +2 -4
- package/dist/features/payments/types/index.js +1 -2
- package/dist/features/products/schemas/index.d.ts +14 -14
- package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
- package/dist/features/promotions/schemas/index.d.ts +20 -20
- package/dist/features/reviews/schemas/index.d.ts +8 -8
- package/dist/features/scams/schemas/index.d.ts +10 -10
- package/dist/features/search/action-index/settings-entries.js +4 -4
- package/dist/features/seller/schemas/index.d.ts +12 -12
- package/dist/features/seller/schemas/order-forms.d.ts +4 -4
- package/dist/features/shipments/schemas/validation.d.ts +28 -28
- package/dist/features/store-extensions/schemas/payout-method-form.d.ts +50 -50
- package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
- package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +10 -10
- package/dist/features/support/schemas/index.d.ts +14 -14
- package/dist/features/tester/actions/checklist-item-actions.d.ts +4 -4
- package/dist/features/tester/schemas/checklist-item-form.d.ts +2 -2
- package/dist/features/tester/seed-data/_money-flows.js +145 -0
- package/dist/features/tester/seed-data/authored/admin__site-system.js +38 -0
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +10 -10
- package/dist/features/tester/seed-data/authored/buying__offers.js +11 -10
- package/dist/features/tester/seed-data/authored/cta-layout__checkout-bottom-bar.js +1 -1
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +24 -12
- package/dist/features/wishlist/schemas/index.d.ts +2 -2
- package/dist/index.d.ts +6 -28
- package/dist/index.js +8 -51
- package/dist/jobs.d.ts +1 -1
- package/dist/jobs.js +1 -1
- package/dist/providers/payment-phonepe/index.d.ts +117 -0
- package/dist/providers/payment-phonepe/index.js +221 -0
- package/dist/providers.d.ts +3 -2
- package/dist/providers.js +3 -2
- package/dist/schemas/registry.d.ts +163 -2623
- package/dist/schemas/registry.js +1 -6
- package/dist/seed/faq-seed-data.js +5 -5
- package/dist/seed/payouts-seed-data.js +3 -3
- package/dist/seed/site-settings-seed-data.js +7 -4
- package/dist/server-entry.d.ts +1 -2
- package/dist/server-entry.js +1 -3
- package/dist/server.d.ts +3 -9
- package/dist/server.js +5 -23
- package/dist/validation/schemas.d.ts +2 -2
- package/package.json +5 -4
- package/dist/_internal/server/features/payments/actions.d.ts +0 -30
- package/dist/_internal/server/features/payments/actions.js +0 -45
- package/dist/_internal/server/features/payments/data.d.ts +0 -13
- package/dist/_internal/server/features/payments/data.js +0 -20
- package/dist/_internal/server/features/payments/index.d.ts +0 -3
- package/dist/_internal/server/features/payments/index.js +0 -3
- package/dist/_internal/server/jobs/core/payoutBatch.d.ts +0 -2
- package/dist/_internal/server/jobs/core/payoutBatch.js +0 -120
- package/dist/_internal/server/jobs/handlers/payoutBatch.d.ts +0 -2
- package/dist/_internal/server/jobs/handlers/payoutBatch.js +0 -2
- package/dist/_internal/shared/features/payments/config.d.ts +0 -3
- package/dist/_internal/shared/features/payments/config.js +0 -3
- package/dist/contracts/client-payment-gateway.d.ts +0 -64
- package/dist/contracts/client-payment-gateway.js +0 -25
- package/dist/features/checkout/hooks/useCheckout.d.ts +0 -9
- package/dist/features/checkout/hooks/useCheckout.js +0 -24
- package/dist/features/checkout/hooks/useCheckoutApi.d.ts +0 -72
- package/dist/features/checkout/hooks/useCheckoutApi.js +0 -47
- package/dist/features/checkout/hooks/usePaymentCheckout.d.ts +0 -77
- package/dist/features/checkout/hooks/usePaymentCheckout.js +0 -192
- package/dist/providers/payment-razorpay/index.d.ts +0 -115
- package/dist/providers/payment-razorpay/index.js +0 -208
- package/dist/schemas/webhooks/razorpay.d.ts +0 -2634
- package/dist/schemas/webhooks/razorpay.js +0 -104
package/dist/schemas/registry.js
CHANGED
|
@@ -187,15 +187,10 @@ const sieve = {
|
|
|
187
187
|
};
|
|
188
188
|
// ---------------------------------------------------------------------------
|
|
189
189
|
// Webhook envelope schemas — W7 cohort. Each provider registers a bucket
|
|
190
|
-
// of `eventName` → schema.
|
|
191
|
-
// keyed on the `event` discriminator.
|
|
190
|
+
// of `eventName` → schema.
|
|
192
191
|
// ---------------------------------------------------------------------------
|
|
193
|
-
import { razorpayWebhookEnvelopeSchema } from "./webhooks/razorpay";
|
|
194
192
|
import { googleSignInWithIdpResponseSchema, googleTokenInfoSchema, } from "./webhooks/google-oauth";
|
|
195
193
|
const webhook = {
|
|
196
|
-
razorpay: {
|
|
197
|
-
envelope: razorpayWebhookEnvelopeSchema,
|
|
198
|
-
},
|
|
199
194
|
googleOauth: {
|
|
200
195
|
signInWithIdp: googleSignInWithIdpResponseSchema,
|
|
201
196
|
tokenInfo: googleTokenInfoSchema,
|
|
@@ -487,17 +487,17 @@ const faqSeedRecords = [
|
|
|
487
487
|
{
|
|
488
488
|
id: "faq-payment-methods",
|
|
489
489
|
question: "What payment methods are accepted?",
|
|
490
|
-
answer: html(`<p>LetItRip's default payment method is <strong>Manual UPI / Bank Transfer</strong> — you pay directly and submit your payment reference, which the seller or LetItRip confirms before shipping. Where enabled, you can also pay instantly via <strong>
|
|
490
|
+
answer: html(`<p>LetItRip's default payment method is <strong>Manual UPI / Bank Transfer</strong> — you pay directly and submit your payment reference, which the seller or LetItRip confirms before shipping. Where enabled, you can also pay instantly via <strong>PhonePe</strong> (cards, UPI, net banking), choose <strong>Cash on Delivery</strong> (a small deposit online plus cash on arrival), or spread the cost with <strong>EMI</strong> on eligible orders. Sellers only receive payout funds after you confirm delivery (or after the dispute window closes).</p>`),
|
|
491
491
|
category: "orders_payment",
|
|
492
492
|
showOnHomepage: true,
|
|
493
493
|
showInFooter: true,
|
|
494
494
|
isPinned: false,
|
|
495
495
|
order: 25,
|
|
496
496
|
priority: 8,
|
|
497
|
-
tags: ["payment", "upi", "
|
|
497
|
+
tags: ["payment", "upi", "phonepe", "cod", "emi"],
|
|
498
498
|
relatedFAQs: ["faq-what-is-escrow", "faq-emi-installments", "faq-payment-proof-verification"],
|
|
499
499
|
stats: makeStats(5100, 255),
|
|
500
|
-
seo: { slug: "faq-payment-methods", metaTitle: "Payment Methods on LetItRip", metaDescription: "Manual UPI,
|
|
500
|
+
seo: { slug: "faq-payment-methods", metaTitle: "Payment Methods on LetItRip", metaDescription: "Manual UPI, PhonePe, Cash on Delivery, and EMI — all payment options on LetItRip." },
|
|
501
501
|
isActive: true,
|
|
502
502
|
createdBy: "user-admin-letitrip",
|
|
503
503
|
createdAt: daysAgo(110),
|
|
@@ -620,14 +620,14 @@ const faqSeedRecords = [
|
|
|
620
620
|
{
|
|
621
621
|
id: "faq-payment-failed",
|
|
622
622
|
question: "My payment failed but money was deducted — what do I do?",
|
|
623
|
-
answer: html(`<p>If your payment fails but the amount is deducted, it's usually a temporary hold by your bank. The amount is auto-reversed within 24–48 hours. If it doesn't reverse after 48 hours, contact your bank with the transaction ID (available in your
|
|
623
|
+
answer: html(`<p>If your payment fails but the amount is deducted, it's usually a temporary hold by your bank. The amount is auto-reversed within 24–48 hours. If it doesn't reverse after 48 hours, contact your bank with the transaction ID (available in your PhonePe receipt email) or reach out to LetItRip support.</p>`),
|
|
624
624
|
category: "orders_payment",
|
|
625
625
|
showOnHomepage: false,
|
|
626
626
|
showInFooter: false,
|
|
627
627
|
isPinned: false,
|
|
628
628
|
order: 30,
|
|
629
629
|
priority: 8,
|
|
630
|
-
tags: ["payment-failed", "bank-hold", "
|
|
630
|
+
tags: ["payment-failed", "bank-hold", "phonepe"],
|
|
631
631
|
relatedFAQs: ["faq-payment-methods"],
|
|
632
632
|
stats: makeStats(3200, 160),
|
|
633
633
|
seo: { slug: "faq-payment-failed", metaTitle: "Payment Failed but Money Deducted", metaDescription: "What to do when payment fails but bank deducts the amount." },
|
|
@@ -266,11 +266,11 @@ export const payoutsSeedData = [
|
|
|
266
266
|
entry(daysAgo(154), "system", "payoutBatch:dispatch", {
|
|
267
267
|
status: { from: "pending", to: "processing" },
|
|
268
268
|
}),
|
|
269
|
-
entry(daysAgo(154), "system", "payoutBatch:failedRetrying", { status: { from: "processing", to: "pending" }, lastFailureReason: { from: null, to: "
|
|
269
|
+
entry(daysAgo(154), "system", "payoutBatch:failedRetrying", { status: { from: "processing", to: "pending" }, lastFailureReason: { from: null, to: "Bank transfer failed: beneficiary bank returned NEFT rejection" } }, { reason: "Bank transfer failed: beneficiary bank returned NEFT rejection" }),
|
|
270
270
|
entry(daysAgo(153), "system", "payoutBatch:dispatch", {
|
|
271
271
|
status: { from: "pending", to: "processing" },
|
|
272
272
|
}),
|
|
273
|
-
entry(daysAgo(153), "system", "payoutBatch:failedFinal", { status: { from: "processing", to: "failed" }, lastFailureReason: { from: "
|
|
273
|
+
entry(daysAgo(153), "system", "payoutBatch:failedFinal", { status: { from: "processing", to: "failed" }, lastFailureReason: { from: "Bank transfer failed: beneficiary bank returned NEFT rejection", to: "Bank transfer failed: IFSC code mismatch" } }, { reason: "Bank transfer failed: IFSC code mismatch" }),
|
|
274
274
|
],
|
|
275
275
|
},
|
|
276
276
|
// 10. Beyblade Arena — Jan 2026 — UPI limit exceeded
|
|
@@ -296,7 +296,7 @@ export const payoutsSeedData = [
|
|
|
296
296
|
entry(daysAgo(109), "system", "payoutBatch:dispatch", {
|
|
297
297
|
status: { from: "pending", to: "processing" },
|
|
298
298
|
}),
|
|
299
|
-
entry(daysAgo(108), "system", "payoutBatch:failedFinal", { status: { from: "processing", to: "failed" }, lastFailureReason: { from: null, to: "
|
|
299
|
+
entry(daysAgo(108), "system", "payoutBatch:failedFinal", { status: { from: "processing", to: "failed" }, lastFailureReason: { from: null, to: "UPI transfer failed: daily limit exceeded" } }, { reason: "UPI transfer failed: daily limit exceeded" }),
|
|
300
300
|
],
|
|
301
301
|
},
|
|
302
302
|
];
|
|
@@ -167,7 +167,7 @@ export const siteSettingsSeedData = {
|
|
|
167
167
|
whatsappNumber: "918919665811",
|
|
168
168
|
},
|
|
169
169
|
payment: {
|
|
170
|
-
|
|
170
|
+
phonepeEnabled: false,
|
|
171
171
|
upiManualEnabled: true,
|
|
172
172
|
codEnabled: true,
|
|
173
173
|
otpCheckoutThreshold: 5000,
|
|
@@ -479,9 +479,12 @@ export const siteSettingsSeedData = {
|
|
|
479
479
|
},
|
|
480
480
|
},
|
|
481
481
|
credentials: {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
482
|
+
phonepeClientId: "PGTESTPAYUAT_PLACEHOLDER",
|
|
483
|
+
phonepeClientSecret: "secret_PLACEHOLDER",
|
|
484
|
+
phonepeClientVersion: "1",
|
|
485
|
+
phonepeEnvironment: "sandbox",
|
|
486
|
+
phonepeWebhookUsername: "webhook_PLACEHOLDER",
|
|
487
|
+
phonepeWebhookPassword: "webhook_PLACEHOLDER",
|
|
485
488
|
resendApiKey: "",
|
|
486
489
|
whatsappApiKey: "wa_PLACEHOLDER",
|
|
487
490
|
// Real Meta secrets — deliberately left empty. With these unset the order
|
package/dist/server-entry.d.ts
CHANGED
|
@@ -66,10 +66,9 @@ export { renderScamOg, renderScamOgImage, type ScamOgData, getScammerForDetail,
|
|
|
66
66
|
export { getSearchResults, searchAction, type SearchQuery, } from "./_internal/server/features/search/index";
|
|
67
67
|
export { getCategoryForDetail, listRootCategories, listFeaturedCategories, listMenuCategories, getCategoryTree, listSitemapCategories, CATEGORIES_PAGE_SIZE, CATEGORIES_ROOT_TIER, CATEGORIES_MAX_DEPTH, CATEGORIES_SITEMAP_LIMIT, CATEGORIES_FEATURED_LIMIT, CATEGORIES_MENU_LIMIT, } from "./_internal/server/features/categories/index";
|
|
68
68
|
export { getGroupedListingForDetail, getGroupedListingWithItems, listGroupedListings, listFeaturedGroupedListings, listSitemapGroupedListings, getGroupsForProduct, getGroupsWithItemsForProduct, GROUPED_LISTINGS_PAGE_SIZE, GROUPED_LISTINGS_FEATURED_LIMIT, GROUPED_LISTINGS_SITEMAP_LIMIT, buildGroupedListingMetadata, renderGroupedListingOg, type GroupedListingWithItems, type ListGroupedListingsParams, type SitemapGroupedListing, type GroupedListingMetadataOptions, } from "./_internal/server/features/grouped/index";
|
|
69
|
-
export { createCheckoutOrderAction, attachPaymentAction,
|
|
69
|
+
export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlacePhonePeOrderAction, previewCheckoutPricing, resolveShippingCost, formatShippingAddress, CHECKOUT_DEFAULT_COMMISSIONS, CHECKOUT_PAYMENT_METHODS, type CreateCheckoutOrderInput, type VerifyAndPlacePhonePeOrderInput, type CheckoutOrderResult, type CheckoutPaymentMethod, type CheckoutPricingPreviewInput, type CheckoutPricingPreview, } from "./_internal/server/features/checkout/index";
|
|
70
70
|
export { unitPriceFor, lineTotalFor, computePreOrderDepositAmount, } from "./_internal/shared/checkout/order-math";
|
|
71
71
|
export { processRefundAction, type ProcessRefundInput, } from "./_internal/server/features/refunds/actions";
|
|
72
|
-
export { createPaymentIntentAction, verifyPaymentSignatureAction, resolvePaymentFee, PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, PAYMENTS_RECEIPT_PREFIX, type CreatePaymentIntentInput, type CreatePaymentIntentResult, type VerifyPaymentSignatureInput, type ResolvedPaymentFee, } from "./_internal/server/features/payments/index";
|
|
73
72
|
export { getSublistingCategoryForDetail } from "./_internal/server/features/sublisting-categories/index";
|
|
74
73
|
export { getStoreForDetail, listStoreProductsInitial, listStoreAuctionsInitial, listStorePreOrdersInitial, listSitemapStores, STORES_PAGE_SIZE, STORES_PRODUCTS_PAGE_SIZE, STORES_SITEMAP_LIMIT, STORES_FEATURED_LIMIT, } from "./_internal/server/features/stores/index";
|
|
75
74
|
export { AppShell } from "./_internal/client/scaffolds/index";
|
package/dist/server-entry.js
CHANGED
|
@@ -96,7 +96,7 @@ export { getGroupedListingForDetail, getGroupedListingWithItems, listGroupedList
|
|
|
96
96
|
// `categoriesRepository.findBySlugAndType(slug, "bundle")` /
|
|
97
97
|
// `.listByType("bundle", opts)` / `.findById(id)` directly.
|
|
98
98
|
// S4: checkout actions
|
|
99
|
-
export { createCheckoutOrderAction, attachPaymentAction,
|
|
99
|
+
export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlacePhonePeOrderAction, previewCheckoutPricing, resolveShippingCost, formatShippingAddress, CHECKOUT_DEFAULT_COMMISSIONS, CHECKOUT_PAYMENT_METHODS, } from "./_internal/server/features/checkout/index";
|
|
100
100
|
// The one definition of "what does this cart line cost". Exported because the
|
|
101
101
|
// consumer's Razorpay create-order route needs it: that route used to hand-roll
|
|
102
102
|
// the rule and reproduced only the bundle branch, so it captured the LIST price
|
|
@@ -104,8 +104,6 @@ export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlaceRazorpayO
|
|
|
104
104
|
export { unitPriceFor, lineTotalFor, computePreOrderDepositAmount, } from "./_internal/shared/checkout/order-math";
|
|
105
105
|
// S-SBUNI-RULES: refund action
|
|
106
106
|
export { processRefundAction, } from "./_internal/server/features/refunds/actions";
|
|
107
|
-
// S4: payments actions
|
|
108
|
-
export { createPaymentIntentAction, verifyPaymentSignatureAction, resolvePaymentFee, PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, PAYMENTS_RECEIPT_PREFIX, } from "./_internal/server/features/payments/index";
|
|
109
107
|
// S3: sublisting categories data layer
|
|
110
108
|
export { getSublistingCategoryForDetail } from "./_internal/server/features/sublisting-categories/index";
|
|
111
109
|
// S3: stores data layer
|
package/dist/server.d.ts
CHANGED
|
@@ -142,15 +142,9 @@ export { buildFirebaseClientConfig } from "./providers/db-firebase/index";
|
|
|
142
142
|
export { normalizeFirebaseConfigValue } from "./providers/db-firebase/index";
|
|
143
143
|
export { prepareForFirestore } from "./providers/db-firebase/index";
|
|
144
144
|
export { createResendProvider } from "./providers/email-resend/index";
|
|
145
|
-
export {
|
|
146
|
-
export {
|
|
147
|
-
export {
|
|
148
|
-
export { fetchRazorpayOrder } from "./providers/payment-razorpay/index";
|
|
149
|
-
export { paiseToRupees } from "./providers/payment-razorpay/index";
|
|
150
|
-
export { rupeesToPaise } from "./providers/payment-razorpay/index";
|
|
151
|
-
export { verifyPaymentSignature } from "./providers/payment-razorpay/index";
|
|
152
|
-
export { verifyPaymentSignatureWithKeys } from "./providers/payment-razorpay/index";
|
|
153
|
-
export { verifyWebhookSignature } from "./providers/payment-razorpay/index";
|
|
145
|
+
export { PhonePeProvider } from "./providers/payment-phonepe/index";
|
|
146
|
+
export { paiseToRupees } from "./core/money";
|
|
147
|
+
export { rupeesToPaise } from "./core/money";
|
|
154
148
|
export { resolveKeys } from "./core/integration-keys";
|
|
155
149
|
export { ManualPaymentProvider } from "./providers/payment-manual/index";
|
|
156
150
|
export { ManualShippingProvider } from "./providers/shipping-manual/index";
|
package/dist/server.js
CHANGED
|
@@ -393,34 +393,16 @@ export { prepareForFirestore } from "./providers/db-firebase/index";
|
|
|
393
393
|
// createResendProvider - Helper for create resend provider.
|
|
394
394
|
export { createResendProvider } from "./providers/email-resend/index";
|
|
395
395
|
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
396
|
-
//
|
|
397
|
-
export {
|
|
398
|
-
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
399
|
-
// createRazorpayOrder - Helper for create razorpay order.
|
|
400
|
-
export { createRazorpayOrder } from "./providers/payment-razorpay/index";
|
|
401
|
-
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
402
|
-
// createRazorpayRefund - Helper for create razorpay refund.
|
|
403
|
-
export { createRazorpayRefund } from "./providers/payment-razorpay/index";
|
|
404
|
-
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
405
|
-
// fetchRazorpayOrder - Shared export for fetch razorpay order.
|
|
406
|
-
export { fetchRazorpayOrder } from "./providers/payment-razorpay/index";
|
|
396
|
+
// PhonePeProvider - Component for phonepe provider.
|
|
397
|
+
export { PhonePeProvider } from "./providers/payment-phonepe/index";
|
|
407
398
|
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
408
399
|
// paiseToRupees - Shared export for paise to rupees. // audit-money-units-ok: names the boundary conversion function itself
|
|
409
|
-
export { paiseToRupees } from "./
|
|
400
|
+
export { paiseToRupees } from "./core/money";
|
|
410
401
|
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
411
402
|
// rupeesToPaise - Shared export for rupees to paise. // audit-money-units-ok: names the boundary conversion function itself
|
|
412
|
-
export { rupeesToPaise } from "./
|
|
413
|
-
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
414
|
-
// verifyPaymentSignature - Shared export for verify payment signature.
|
|
415
|
-
export { verifyPaymentSignature } from "./providers/payment-razorpay/index";
|
|
416
|
-
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
417
|
-
// verifyPaymentSignatureWithKeys - Shared export for verify payment signature with keys.
|
|
418
|
-
export { verifyPaymentSignatureWithKeys } from "./providers/payment-razorpay/index";
|
|
419
|
-
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
420
|
-
// verifyWebhookSignature - Shared export for verify webhook signature.
|
|
421
|
-
export { verifyWebhookSignature } from "./providers/payment-razorpay/index";
|
|
403
|
+
export { rupeesToPaise } from "./core/money";
|
|
422
404
|
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
423
|
-
// resolveKeys - resolves integration credentials (
|
|
405
|
+
// resolveKeys - resolves integration credentials (PhonePe etc.) from Firestore site settings, falling back to env vars. Used by providers.config.ts to construct PhonePeProvider when siteSettings.payment.phonepeEnabled is true.
|
|
424
406
|
export { resolveKeys } from "./core/integration-keys";
|
|
425
407
|
// [SERVER-ONLY]-Server-only — uses Node.js, Next.js server internals, or third-party server SDKs (auth, email, payment, shipping).
|
|
426
408
|
// ManualPaymentProvider - the default IPaymentProvider implementation (no gateway).
|
|
@@ -7,16 +7,16 @@ export declare const paginationQuerySchema: z.ZodObject<{
|
|
|
7
7
|
search: z.ZodOptional<z.ZodString>;
|
|
8
8
|
}, "strip", z.ZodTypeAny, {
|
|
9
9
|
page: number;
|
|
10
|
-
sortOrder: "desc" | "asc";
|
|
11
10
|
limit: number;
|
|
11
|
+
sortOrder: "desc" | "asc";
|
|
12
12
|
search?: string | undefined;
|
|
13
13
|
sortBy?: string | undefined;
|
|
14
14
|
}, {
|
|
15
15
|
search?: string | undefined;
|
|
16
16
|
page?: number | undefined;
|
|
17
|
-
sortOrder?: "desc" | "asc" | undefined;
|
|
18
17
|
limit?: number | undefined;
|
|
19
18
|
sortBy?: string | undefined;
|
|
19
|
+
sortOrder?: "desc" | "asc" | undefined;
|
|
20
20
|
}>;
|
|
21
21
|
export declare const objectIdSchema: z.ZodString;
|
|
22
22
|
export declare const urlSchema: z.ZodString;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mohasinac/appkit",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.42.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -174,6 +174,7 @@
|
|
|
174
174
|
"driver.js": "^1.8.0",
|
|
175
175
|
"jsbarcode": "^3.12.3",
|
|
176
176
|
"motion": "^13.1.1",
|
|
177
|
+
"phonepe-pg-sdk-node": "^2.0.2",
|
|
177
178
|
"react-advanced-cropper": "^0.20.1",
|
|
178
179
|
"tailwind-merge": "^3.3.0",
|
|
179
180
|
"zod": "^3.24.0",
|
|
@@ -187,7 +188,7 @@
|
|
|
187
188
|
"firebase-functions": "^7.3.2",
|
|
188
189
|
"next": ">=14",
|
|
189
190
|
"next-intl": ">=3",
|
|
190
|
-
"
|
|
191
|
+
"phonepe-pg-sdk-node": ">=2.0.2",
|
|
191
192
|
"react": ">=18",
|
|
192
193
|
"react-dom": ">=18",
|
|
193
194
|
"recharts": "^3.8.1",
|
|
@@ -203,7 +204,7 @@
|
|
|
203
204
|
"resend": {
|
|
204
205
|
"optional": true
|
|
205
206
|
},
|
|
206
|
-
"
|
|
207
|
+
"phonepe-pg-sdk-node": {
|
|
207
208
|
"optional": true
|
|
208
209
|
},
|
|
209
210
|
"@tanstack/react-query": {
|
|
@@ -231,7 +232,7 @@
|
|
|
231
232
|
"lucide-react": "^1.33.0",
|
|
232
233
|
"next": "^15.0.0",
|
|
233
234
|
"next-intl": "^4.9.1",
|
|
234
|
-
"
|
|
235
|
+
"phonepe-pg-sdk-node": "^2.0.2",
|
|
235
236
|
"react": "^19.2.0",
|
|
236
237
|
"react-dom": "^19.2.0",
|
|
237
238
|
"resend": "^6.10.0",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Payments server actions (appkit).
|
|
3
|
-
*
|
|
4
|
-
* Wraps the Razorpay primitives in a single createPaymentIntentAction. The
|
|
5
|
-
* existing /api/payment/create-order route becomes a thin wrapper over this
|
|
6
|
-
* once consumer wiring lands (S7). Webhook + verify routes remain in the
|
|
7
|
-
* consumer because they parse provider-specific request bodies.
|
|
8
|
-
*/
|
|
9
|
-
export interface CreatePaymentIntentInput {
|
|
10
|
-
userId: string;
|
|
11
|
-
/** Base amount in rupees (the cart total before the Razorpay fee). */
|
|
12
|
-
amount: number;
|
|
13
|
-
currency?: string;
|
|
14
|
-
receipt?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface CreatePaymentIntentResult {
|
|
17
|
-
razorpayOrderId: string;
|
|
18
|
-
amount: number;
|
|
19
|
-
currency: string;
|
|
20
|
-
keyId: string;
|
|
21
|
-
platformFee: number;
|
|
22
|
-
baseAmount: number;
|
|
23
|
-
}
|
|
24
|
-
export declare function createPaymentIntentAction(input: CreatePaymentIntentInput): Promise<CreatePaymentIntentResult>;
|
|
25
|
-
export interface VerifyPaymentSignatureInput {
|
|
26
|
-
orderId: string;
|
|
27
|
-
paymentId: string;
|
|
28
|
-
signature: string;
|
|
29
|
-
}
|
|
30
|
-
export declare function verifyPaymentSignatureAction(input: VerifyPaymentSignatureInput): Promise<boolean>;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Payments server actions (appkit).
|
|
3
|
-
*
|
|
4
|
-
* Wraps the Razorpay primitives in a single createPaymentIntentAction. The
|
|
5
|
-
* existing /api/payment/create-order route becomes a thin wrapper over this
|
|
6
|
-
* once consumer wiring lands (S7). Webhook + verify routes remain in the
|
|
7
|
-
* consumer because they parse provider-specific request bodies.
|
|
8
|
-
*/
|
|
9
|
-
import { ApiError } from "../../../../errors";
|
|
10
|
-
import { serverLogger } from "../../../../monitoring";
|
|
11
|
-
import { createRazorpayOrder, rupeesToPaise, verifyPaymentSignatureWithKeys, } from "../../../../providers/payment-razorpay/index";
|
|
12
|
-
import { getDefaultCurrency } from "../../../../core/index";
|
|
13
|
-
import { PAYMENTS_RECEIPT_PREFIX } from "../../../shared/features/payments/config";
|
|
14
|
-
import { resolvePaymentFee } from "./data";
|
|
15
|
-
export async function createPaymentIntentAction(input) {
|
|
16
|
-
const keyId = process.env.RAZORPAY_KEY_ID;
|
|
17
|
-
if (!keyId) {
|
|
18
|
-
throw new ApiError(500, "Razorpay is not configured on this server");
|
|
19
|
-
}
|
|
20
|
-
const currency = input.currency ?? getDefaultCurrency();
|
|
21
|
-
const fee = await resolvePaymentFee(input.amount);
|
|
22
|
-
const amountInPaise = rupeesToPaise(fee.totalAmount);
|
|
23
|
-
const razorpayOrder = await createRazorpayOrder({
|
|
24
|
-
amount: amountInPaise,
|
|
25
|
-
currency,
|
|
26
|
-
receipt: input.receipt ?? `${PAYMENTS_RECEIPT_PREFIX}${input.userId}_${Date.now()}`,
|
|
27
|
-
notes: { userId: input.userId },
|
|
28
|
-
});
|
|
29
|
-
serverLogger.info(`createPaymentIntentAction: ${razorpayOrder.id} uid=${input.userId} base=${fee.baseAmount} fee=${fee.platformFee} total=${fee.totalAmount}`);
|
|
30
|
-
return {
|
|
31
|
-
razorpayOrderId: razorpayOrder.id,
|
|
32
|
-
amount: razorpayOrder.amount,
|
|
33
|
-
currency: razorpayOrder.currency,
|
|
34
|
-
keyId,
|
|
35
|
-
platformFee: fee.platformFee,
|
|
36
|
-
baseAmount: fee.baseAmount,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
export async function verifyPaymentSignatureAction(input) {
|
|
40
|
-
return verifyPaymentSignatureWithKeys({
|
|
41
|
-
razorpay_order_id: input.orderId,
|
|
42
|
-
razorpay_payment_id: input.paymentId,
|
|
43
|
-
razorpay_signature: input.signature,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface ResolvedPaymentFee {
|
|
2
|
-
baseAmount: number;
|
|
3
|
-
platformFee: number;
|
|
4
|
-
gstOnFee: number;
|
|
5
|
-
totalAmount: number;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Inflates the cart total by our platform fee + GST on that fee.
|
|
9
|
-
* platformFeePercent = siteSettings.commissions.platformFeePercent (our cut %).
|
|
10
|
-
* gstPercent = siteSettings.commissions.gstPercent (18% GST on our fee, not on full order).
|
|
11
|
-
* minimumTransactionFee = per-gateway-transaction floor in rupees.
|
|
12
|
-
*/
|
|
13
|
-
export declare function resolvePaymentFee(baseAmount: number): Promise<ResolvedPaymentFee>;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { siteSettingsRepository } from "../../../../repositories";
|
|
2
|
-
import { roundRupees } from "../../../../utils/number.formatter";
|
|
3
|
-
import { PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, } from "../../../shared/features/payments/config";
|
|
4
|
-
/**
|
|
5
|
-
* Inflates the cart total by our platform fee + GST on that fee.
|
|
6
|
-
* platformFeePercent = siteSettings.commissions.platformFeePercent (our cut %).
|
|
7
|
-
* gstPercent = siteSettings.commissions.gstPercent (18% GST on our fee, not on full order).
|
|
8
|
-
* minimumTransactionFee = per-gateway-transaction floor in rupees.
|
|
9
|
-
*/
|
|
10
|
-
export async function resolvePaymentFee(baseAmount) {
|
|
11
|
-
const siteSettings = await siteSettingsRepository.getSingleton();
|
|
12
|
-
const platformFeePercent = siteSettings?.commissions?.platformFeePercent ?? PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT;
|
|
13
|
-
const gstPercent = siteSettings?.commissions?.gstPercent ?? PAYMENTS_DEFAULT_GST_PERCENT;
|
|
14
|
-
const minimumTransactionFee = Math.max(0, siteSettings?.commissions?.minimumTransactionFee ?? 0);
|
|
15
|
-
const platformFee = roundRupees(baseAmount * (platformFeePercent / 100));
|
|
16
|
-
const gstOnFee = roundRupees(platformFee * (gstPercent / 100));
|
|
17
|
-
const rawTotal = baseAmount + platformFee + gstOnFee;
|
|
18
|
-
const totalAmount = Math.max(rawTotal, baseAmount + minimumTransactionFee);
|
|
19
|
-
return { baseAmount, platformFee, gstOnFee, totalAmount };
|
|
20
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { createPaymentIntentAction, verifyPaymentSignatureAction, type CreatePaymentIntentInput, type CreatePaymentIntentResult, type VerifyPaymentSignatureInput, } from "./actions";
|
|
2
|
-
export { resolvePaymentFee, type ResolvedPaymentFee } from "./data";
|
|
3
|
-
export { PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, PAYMENTS_RECEIPT_PREFIX, } from "../../../shared/features/payments/config";
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export { createPaymentIntentAction, verifyPaymentSignatureAction, } from "./actions";
|
|
2
|
-
export { resolvePaymentFee } from "./data";
|
|
3
|
-
export { PAYMENTS_DEFAULT_PLATFORM_FEE_PERCENT, PAYMENTS_DEFAULT_GST_PERCENT, PAYMENTS_RECEIPT_PREFIX, } from "../../../shared/features/payments/config";
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { normalizeError } from "../../../../errors/normalize";
|
|
2
|
-
/**
|
|
3
|
-
* Core: dispatch pending payouts via Razorpay Payouts API.
|
|
4
|
-
*
|
|
5
|
-
* Reads RAZORPAY_KEY_ID / RAZORPAY_KEY_SECRET / RAZORPAY_ACCOUNT_NUMBER from
|
|
6
|
-
* env (via `ctx.env`). On 3rd consecutive failure the record is marked failed.
|
|
7
|
-
*/
|
|
8
|
-
import { payoutRepository } from "../../../../repositories";
|
|
9
|
-
const MAX_FAILURES = 3;
|
|
10
|
-
async function dispatch(ctx, entry) {
|
|
11
|
-
const { ref, data: payout } = entry;
|
|
12
|
-
/*
|
|
13
|
-
* The batch's running copy of the document, threaded through every write.
|
|
14
|
-
*
|
|
15
|
-
* Two reasons it is not just `payout`. (a) The snapshot came from the
|
|
16
|
-
* pending query, so history costs no extra read. (b) The sequence is
|
|
17
|
-
* pending → processing → failed; diffing the final write against the
|
|
18
|
-
* ORIGINAL snapshot would record "pending → failed" and lose the dispatch
|
|
19
|
-
* attempt that is the whole reason anyone opens the timeline.
|
|
20
|
-
*/
|
|
21
|
-
let current = payout;
|
|
22
|
-
const actor = { role: "system" };
|
|
23
|
-
await payoutRepository.markProcessing(ref, { actor }, current);
|
|
24
|
-
current = { ...current, status: "processing" };
|
|
25
|
-
try {
|
|
26
|
-
const keyId = ctx.env("RAZORPAY_KEY_ID") ?? "";
|
|
27
|
-
const keySecret = ctx.env("RAZORPAY_KEY_SECRET") ?? "";
|
|
28
|
-
const accountNumber = ctx.env("RAZORPAY_ACCOUNT_NUMBER") ?? "";
|
|
29
|
-
const apiBaseUrl = ctx.env("RAZORPAY_API_BASE_URL") ?? "https://api.razorpay.com/v1";
|
|
30
|
-
const brandName = ctx.env("APP_BRAND_NAME") ?? "";
|
|
31
|
-
if (!keyId || !keySecret || !accountNumber) {
|
|
32
|
-
throw new Error("Razorpay credentials not configured");
|
|
33
|
-
}
|
|
34
|
-
const basicAuth = Buffer.from(`${keyId}:${keySecret}`).toString("base64");
|
|
35
|
-
let fundAccount;
|
|
36
|
-
if (payout.paymentMethod === "upi" && payout.upiId) {
|
|
37
|
-
fundAccount = { account_type: "vpa", vpa: { address: payout.upiId } };
|
|
38
|
-
}
|
|
39
|
-
else if (payout.bankAccount) {
|
|
40
|
-
fundAccount = {
|
|
41
|
-
account_type: "bank_account",
|
|
42
|
-
bank_account: {
|
|
43
|
-
name: payout.bankAccount.accountHolderName,
|
|
44
|
-
ifsc: payout.bankAccount.ifscCode,
|
|
45
|
-
account_number: payout.bankAccount.accountNumberMasked,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
throw new Error("Payout has no fund account configured");
|
|
51
|
-
}
|
|
52
|
-
const payload = {
|
|
53
|
-
account_number: accountNumber,
|
|
54
|
-
fund_account: {
|
|
55
|
-
...fundAccount,
|
|
56
|
-
contact: { name: payout.sellerEmail, type: "vendor", email: payout.sellerEmail },
|
|
57
|
-
},
|
|
58
|
-
// Use netAmount when refund deductions have been applied, otherwise gross amount.
|
|
59
|
-
amount: Math.round((payout.netAmount ?? payout.amount) * 100),
|
|
60
|
-
currency: payout.currency.toUpperCase(),
|
|
61
|
-
mode: payout.paymentMethod === "upi" ? "UPI" : "NEFT",
|
|
62
|
-
purpose: "payout",
|
|
63
|
-
reference_id: payout.id,
|
|
64
|
-
narration: brandName
|
|
65
|
-
? `${brandName} payout for seller ${payout.storeId}`
|
|
66
|
-
: `Payout for seller ${payout.storeId}`,
|
|
67
|
-
};
|
|
68
|
-
const response = await fetch(`${apiBaseUrl}/payouts`, {
|
|
69
|
-
method: "POST",
|
|
70
|
-
headers: {
|
|
71
|
-
Authorization: `Basic ${basicAuth}`,
|
|
72
|
-
"Content-Type": "application/json",
|
|
73
|
-
"X-Payout-Idempotency": payout.id,
|
|
74
|
-
},
|
|
75
|
-
body: JSON.stringify(payload),
|
|
76
|
-
});
|
|
77
|
-
if (!response.ok) {
|
|
78
|
-
const errBody = await response.text();
|
|
79
|
-
throw new Error(`Razorpay ${response.status}: ${errBody}`);
|
|
80
|
-
}
|
|
81
|
-
const result = (await response.json());
|
|
82
|
-
await payoutRepository.recordSuccess(ref, result.id, result.status, { actor }, current);
|
|
83
|
-
ctx.logger.info(`Payout ${payout.id} dispatched`, { razorpayId: result.id, razorpayStatus: result.status });
|
|
84
|
-
}
|
|
85
|
-
catch (error) {
|
|
86
|
-
void normalizeError(error);
|
|
87
|
-
const failureCount = (payout.failureCount ?? 0) + 1;
|
|
88
|
-
const isFinal = failureCount >= MAX_FAILURES;
|
|
89
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
90
|
-
await payoutRepository.recordFailure(ref, failureCount, reason, isFinal, { actor }, current);
|
|
91
|
-
if (isFinal) {
|
|
92
|
-
ctx.logger.error(`Payout ${payout.id} permanently failed after ${MAX_FAILURES} attempts`, error, {
|
|
93
|
-
sellerId: payout.storeId,
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
ctx.logger.warn(`Payout ${payout.id} failed (attempt ${failureCount})`, { error: reason });
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
export async function runPayoutBatch(ctx) {
|
|
102
|
-
if (ctx.env("FEATURE_PAYOUTS") !== "true") {
|
|
103
|
-
ctx.logger.info("FEATURE_PAYOUTS disabled — skipping payout batch");
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
ctx.logger.info("Starting payout batch sweep");
|
|
107
|
-
const pending = await payoutRepository.getPending();
|
|
108
|
-
if (pending.length === 0) {
|
|
109
|
-
ctx.logger.info("No pending payouts to process");
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
ctx.logger.info(`Dispatching ${pending.length} payout(s)`);
|
|
113
|
-
const results = await Promise.allSettled(pending.map((entry) => dispatch(ctx, entry)));
|
|
114
|
-
const failed = results.filter((r) => r.status === "rejected").length;
|
|
115
|
-
ctx.logger.info("Payout batch complete", {
|
|
116
|
-
total: pending.length,
|
|
117
|
-
succeeded: pending.length - failed,
|
|
118
|
-
failed,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side payment gateway contract.
|
|
3
|
-
*
|
|
4
|
-
* Abstracts the browser-side interaction with a payment gateway SDK
|
|
5
|
-
* (script loading, modal/redirect, payment response) so checkout hooks
|
|
6
|
-
* never import a vendor-specific SDK directly.
|
|
7
|
-
*
|
|
8
|
-
* Implementations: Razorpay, Stripe, PayPal, etc.
|
|
9
|
-
*/
|
|
10
|
-
import type { PaymentGateway } from "../features/payments/schemas";
|
|
11
|
-
/** Vendor-neutral payment response returned after the user completes payment. */
|
|
12
|
-
export interface GatewayPaymentResponse {
|
|
13
|
-
/** Gateway-assigned order ID (e.g. Razorpay `order_xxx`, Stripe `pi_xxx`). */
|
|
14
|
-
gatewayOrderId: string;
|
|
15
|
-
/** Gateway-assigned payment ID. */
|
|
16
|
-
gatewayPaymentId: string;
|
|
17
|
-
/** Cryptographic signature for server-side verification (if gateway provides one). */
|
|
18
|
-
gatewaySignature?: string;
|
|
19
|
-
}
|
|
20
|
-
/** Options passed to the gateway when opening the payment modal/redirect. */
|
|
21
|
-
export interface OpenGatewayOptions {
|
|
22
|
-
/** Gateway-assigned order/session ID. */
|
|
23
|
-
gatewayOrderId: string;
|
|
24
|
-
/** Public key / publishable key for the gateway SDK. */
|
|
25
|
-
publicKey: string;
|
|
26
|
-
/** Amount in the gateway's smallest currency unit (e.g. paise, cents). */ amount: number;
|
|
27
|
-
/** ISO 4217 currency code. */
|
|
28
|
-
currency: string;
|
|
29
|
-
/** Display name shown in the payment modal. */
|
|
30
|
-
merchantName?: string;
|
|
31
|
-
/** Order description. */
|
|
32
|
-
description?: string;
|
|
33
|
-
/** Logo URL for the payment modal. */
|
|
34
|
-
logoUrl?: string;
|
|
35
|
-
/** Prefill customer details. */
|
|
36
|
-
prefill?: {
|
|
37
|
-
name?: string;
|
|
38
|
-
email?: string;
|
|
39
|
-
phone?: string;
|
|
40
|
-
};
|
|
41
|
-
/** Theme/branding overrides. */
|
|
42
|
-
theme?: {
|
|
43
|
-
color?: string;
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
export interface IClientPaymentGateway {
|
|
47
|
-
/** Which gateway this adapter handles. */
|
|
48
|
-
readonly gateway: PaymentGateway;
|
|
49
|
-
/**
|
|
50
|
-
* Load the gateway's client-side SDK script.
|
|
51
|
-
* Implementations should be idempotent (no-op if already loaded).
|
|
52
|
-
* @returns `true` when the SDK is ready to use.
|
|
53
|
-
*/
|
|
54
|
-
loadScript(): Promise<boolean>;
|
|
55
|
-
/**
|
|
56
|
-
* Open the payment modal or redirect to the gateway's hosted page.
|
|
57
|
-
* Resolves with the payment response on success.
|
|
58
|
-
* Rejects if the user cancels or a gateway error occurs.
|
|
59
|
-
*/
|
|
60
|
-
openPayment(options: OpenGatewayOptions): Promise<GatewayPaymentResponse>;
|
|
61
|
-
}
|
|
62
|
-
export declare function registerClientPaymentGateway(adapter: IClientPaymentGateway): void;
|
|
63
|
-
export declare function getClientPaymentGateway(gateway: PaymentGateway): IClientPaymentGateway;
|
|
64
|
-
export declare function getRegisteredPaymentGateways(): PaymentGateway[];
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Client-side payment gateway contract.
|
|
3
|
-
*
|
|
4
|
-
* Abstracts the browser-side interaction with a payment gateway SDK
|
|
5
|
-
* (script loading, modal/redirect, payment response) so checkout hooks
|
|
6
|
-
* never import a vendor-specific SDK directly.
|
|
7
|
-
*
|
|
8
|
-
* Implementations: Razorpay, Stripe, PayPal, etc.
|
|
9
|
-
*/
|
|
10
|
-
// --- Runtime Registry ------------------------------------------------------
|
|
11
|
-
const _gateways = new Map();
|
|
12
|
-
export function registerClientPaymentGateway(adapter) {
|
|
13
|
-
_gateways.set(adapter.gateway, adapter);
|
|
14
|
-
}
|
|
15
|
-
export function getClientPaymentGateway(gateway) {
|
|
16
|
-
const adapter = _gateways.get(gateway);
|
|
17
|
-
if (!adapter) {
|
|
18
|
-
throw new Error(`Client payment gateway "${gateway}" not registered. ` +
|
|
19
|
-
`Call registerClientPaymentGateway() with a ${gateway} adapter first.`);
|
|
20
|
-
}
|
|
21
|
-
return adapter;
|
|
22
|
-
}
|
|
23
|
-
export function getRegisteredPaymentGateways() {
|
|
24
|
-
return Array.from(_gateways.keys());
|
|
25
|
-
}
|