@arcblock/payment-service 1.29.8 → 1.29.10

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.
Files changed (184) hide show
  1. package/dist/cf.d.ts +31 -0
  2. package/dist/cf.js +79 -60
  3. package/dist/index.js +358 -87
  4. package/package.json +4 -4
  5. package/web/assets/{account-DETfFe4_.js → account-DrsnH5wP.js} +1 -1
  6. package/web/assets/{action-B_DQJlip.js → action-C2c0yWuW.js} +1 -1
  7. package/web/assets/{actions-Bt_jST94.js → actions--FNKSNIs.js} +1 -1
  8. package/web/assets/{actions-jxGAdGfb.js → actions-BEUwbsq1.js} +1 -1
  9. package/web/assets/{actions-D9MHLBFH.js → actions-C9AfME83.js} +1 -1
  10. package/web/assets/{actions-QPa-8lfB.js → actions-D2-s31n3.js} +1 -1
  11. package/web/assets/{actions-DJyfN5OU.js → actions-DXMceTgd.js} +1 -1
  12. package/web/assets/{actions-BtaoyTWt.js → actions-DeCPtfTK.js} +1 -1
  13. package/web/assets/{actions-BaDh4xWX.js → actions-DtNZGZWf.js} +1 -1
  14. package/web/assets/{actions-EPYeS5p4.js → actions-JHsqbHpB.js} +1 -1
  15. package/web/assets/{actions-BknL4OyZ.js → actions-izdZ2Mn4.js} +1 -1
  16. package/web/assets/{add-price-CD-utowo.js → add-price-TdXAR3NW.js} +1 -1
  17. package/web/assets/{admin-_nEB-lHn.js → admin-BpFv3eF5.js} +1 -1
  18. package/web/assets/{assign-CkV5Q2LP.js → assign-DKRfmN7W.js} +1 -1
  19. package/web/assets/{attempts-DySeqBYU.js → attempts-BfbYfiJa.js} +1 -1
  20. package/web/assets/browser-DF2vfpBa.js +1 -0
  21. package/web/assets/{change-payment-CPUCUEER.js → change-payment-j5UC8_h0.js} +1 -1
  22. package/web/assets/{change-plan-CxE-XfWc.js → change-plan-CtXvsIDw.js} +1 -1
  23. package/web/assets/{click-boundary-y8dVA_tr.js → click-boundary-Bi28Y0Fq.js} +1 -1
  24. package/web/assets/{connect-CC_l_f6Q.js → connect-CXek4LAE.js} +1 -1
  25. package/web/assets/{copyable-DpX04wZz.js → copyable-CprMHdhV.js} +1 -1
  26. package/web/assets/{create-Bs65p5Ne.js → create-B-Ubepl_.js} +1 -1
  27. package/web/assets/{create-tYebjhr9.js → create-BVt_sQ_7.js} +1 -1
  28. package/web/assets/{create-3SsWCAOC.js → create-BWviSWbC.js} +1 -1
  29. package/web/assets/{create-BkQAaSvD.js → create-C6jihslA.js} +1 -1
  30. package/web/assets/{create-BmcRybZ5.js → create-IaalYGmm.js} +1 -1
  31. package/web/assets/{create-kG09X9gl.js → create-jzl1m8ZK.js} +1 -1
  32. package/web/assets/{credit-grant-item-list-Bk27jIc7.js → credit-grant-item-list-DQcvdSRs.js} +1 -1
  33. package/web/assets/{credit-overview-DmMSEs14.js → credit-overview-CPId2vzk.js} +2 -2
  34. package/web/assets/{currency-restrictions-DYLv4YyW.js → currency-restrictions-Dsupz2ce.js} +1 -1
  35. package/web/assets/{currency-select-DGS-62-L.js → currency-select-C8j7QQMP.js} +1 -1
  36. package/web/assets/{dayjs-B9tvQIKg.js → dayjs-DUNWtvju.js} +1 -1
  37. package/web/assets/{description-Ym17DL48.js → description-BHxdy5I3.js} +1 -1
  38. package/web/assets/{detail-DPCTQLOx.js → detail-B17BN6kU.js} +1 -1
  39. package/web/assets/detail-BJ-hl5PK.js +10 -0
  40. package/web/assets/detail-BJEqTXDS.js +1 -0
  41. package/web/assets/{detail-DG4l2CqN.js → detail-BdC9VIc6.js} +1 -1
  42. package/web/assets/detail-BkRkrKyw.js +1 -0
  43. package/web/assets/{detail-DuWdZIyp.js → detail-BvcI9cB_.js} +1 -1
  44. package/web/assets/detail-C--ATvwm.js +24 -0
  45. package/web/assets/{detail-Cb9HBSMw.js → detail-CHJqYZ0W.js} +1 -1
  46. package/web/assets/detail-CfvKZ7IV.js +1 -0
  47. package/web/assets/{detail-K9EVY3r2.js → detail-CmIweOLE.js} +1 -1
  48. package/web/assets/{detail-CxYQYu_l.js → detail-D729Bgs6.js} +1 -1
  49. package/web/assets/detail-DD1YBtex.js +1 -0
  50. package/web/assets/detail-DOcm4Kqg.js +15 -0
  51. package/web/assets/{detail-Do9QO5L2.js → detail-DQj1mbhA.js} +1 -1
  52. package/web/assets/detail-DTXDMIR9.js +15 -0
  53. package/web/assets/{detail-DB56SG-k.js → detail-DUAJzKsu.js} +1 -1
  54. package/web/assets/detail-De8PyTyx.js +1 -0
  55. package/web/assets/{detail-CT9Unyrf.js → detail-DqfxOHky.js} +1 -1
  56. package/web/assets/{detail-cwHZbY62.js → detail-Dzt5tfyZ.js} +1 -1
  57. package/web/assets/{detail-D5KRrQDx.js → detail-H0dkKVyS.js} +1 -1
  58. package/web/assets/{detail-DuO_Jn5X.js → detail-MgdgGj5J.js} +1 -1
  59. package/web/assets/{detail-BJTcK7mx.js → detail-WAmPM6yq.js} +1 -1
  60. package/web/assets/{detail-Cr2wG4Th.js → detail-g6el9Fxj.js} +1 -1
  61. package/web/assets/did-Bqcz-NjH.js +1 -0
  62. package/web/assets/{drawer-form-Cl0T1Yyt.js → drawer-form-CQjNFFWk.js} +1 -1
  63. package/web/assets/{edit-3HUAnaXW.js → edit-DAU8AWzT.js} +1 -1
  64. package/web/assets/{editor-BF5I0siU.js → editor-vZvxDUTl.js} +1 -1
  65. package/web/assets/{embed-CsNqeCd0.js → embed-ClYNqZbf.js} +1 -1
  66. package/web/assets/{filter-toolbar-BydfQ-79.js → filter-toolbar-VvmMATj0.js} +1 -1
  67. package/web/assets/form-4_MzglPj.js +9 -0
  68. package/web/assets/{form-P4luyUpY.js → form-AFzUvoFE.js} +1 -1
  69. package/web/assets/{form-DSzMo9UD.js → form-Bro99BjK.js} +1 -1
  70. package/web/assets/{form-BGm5NPDn.js → form-CnrBCyTJ.js} +1 -1
  71. package/web/assets/form-Cuvruf4H.js +16 -0
  72. package/web/assets/{gas-Qf0SSUfS.js → gas-kw2KMH1u.js} +1 -1
  73. package/web/assets/{generateCategoricalChart-BaWwaXky.js → generateCategoricalChart-BCpuUeC_.js} +1 -1
  74. package/web/assets/{home-HbrLyxJL.js → home-ZNJREzbw.js} +1 -1
  75. package/web/assets/{index-BIoSdRvX.js → index-ASk8vU2H.js} +3 -3
  76. package/web/assets/{index-B1pTTyGZ.js → index-B4n6PvPu.js} +1 -1
  77. package/web/assets/{index-DgSc1Qy8.js → index-B4yaPb7B.js} +17 -17
  78. package/web/assets/{index-CI_EY4YS.js → index-BHwID_s4.js} +1 -1
  79. package/web/assets/index-BMcnd_jZ.js +1 -0
  80. package/web/assets/{index-9xBRL_33.js → index-BRmN8ViQ.js} +1 -1
  81. package/web/assets/index-BdbLl6St.js +1 -0
  82. package/web/assets/{index-Cw0ugaQL.js → index-BjKRyxNQ.js} +1 -1
  83. package/web/assets/index-BjLJQRKY.js +1 -0
  84. package/web/assets/index-BkNCPnTn.js +1 -0
  85. package/web/assets/index-BlAwTTmu.js +1 -0
  86. package/web/assets/{index-C0JaS08f.js → index-BtWfmATr.js} +1 -1
  87. package/web/assets/{index-DE2KzqXl.js → index-C-5n472s.js} +1 -1
  88. package/web/assets/{index-Br7_mvEw.js → index-C3AP4jq0.js} +1 -1
  89. package/web/assets/{index-2l22EYw9.js → index-C3Rh1SaB.js} +1 -1
  90. package/web/assets/index-CDyxbCzc.js +1 -0
  91. package/web/assets/{index-Dc954mDP.js → index-CH_k9MVv.js} +1 -1
  92. package/web/assets/{index-1y9kjPIr.js → index-CKPfOW6M.js} +1 -1
  93. package/web/assets/{index-Dr_MwbKt.js → index-CPFlZhA2.js} +1 -1
  94. package/web/assets/index-CPyGjEd3.js +49 -0
  95. package/web/assets/index-ChC-jsE2.js +1 -0
  96. package/web/assets/index-CiWvs3j9.js +1 -0
  97. package/web/assets/{index-BP53rZV9.js → index-D6gv9jHh.js} +1 -1
  98. package/web/assets/{index-CdkYrABk.js → index-D7pWd60Z.js} +1 -1
  99. package/web/assets/{index-fswPX_qe.js → index-DAen2-cr.js} +1 -1
  100. package/web/assets/{index-DPodCQ9c.js → index-DNobX-Tr.js} +1 -1
  101. package/web/assets/{index-Drav4oDH.js → index-DY-g0BPU.js} +2 -2
  102. package/web/assets/index-DZkpxY-C.js +1 -0
  103. package/web/assets/{index-BFML4-2u.js → index-Dh9agU9O.js} +1 -1
  104. package/web/assets/index-Dju8k6mq.js +1 -0
  105. package/web/assets/{index-fByZjxLy.js → index-DwDNPqjF.js} +1 -1
  106. package/web/assets/index-Dze0CpfQ.js +14 -0
  107. package/web/assets/{index-BMKZToMM.js → index-eDERHpkr.js} +2 -2
  108. package/web/assets/{index-SYTpMMMH.js → index-mgPU1lyd.js} +1 -1
  109. package/web/assets/{index-DZpJPE1Z.js → index-olGOY5KB.js} +1 -1
  110. package/web/assets/{index-Clbt8nRm.js → index-oy7LrXGT.js} +1 -1
  111. package/web/assets/index-x7sBb6oM.js +1 -0
  112. package/web/assets/{index.es-BWnfUzLb.js → index.es-C2Q6Owow.js} +1 -1
  113. package/web/assets/{info-card-C1yxhxJG.js → info-card-C9dRgztS.js} +1 -1
  114. package/web/assets/{info-metric-CNse3r66.js → info-metric-ukWq8INi.js} +1 -1
  115. package/web/assets/{info-row-DOK2whMn.js → info-row-CaPaNF4L.js} +1 -1
  116. package/web/assets/{info-row-group-BeUhWnnY.js → info-row-group-Cxo-4Gk5.js} +1 -1
  117. package/web/assets/{libphonenumber-CyphiuxQ.js → libphonenumber-CTvobi0D.js} +1 -1
  118. package/web/assets/{link-3eeclTeS.js → link-DsltSF2Q.js} +1 -1
  119. package/web/assets/{list-C521zE_7.js → list-B2b-s8wM.js} +1 -1
  120. package/web/assets/{list-CO0X4L3-.js → list-BzgF4i3i.js} +1 -1
  121. package/web/assets/{list-DnePqZ2K.js → list-Cd1O-aDi.js} +1 -1
  122. package/web/assets/{list-D1aevUOI.js → list-CvM46TsP.js} +2 -2
  123. package/web/assets/{list-jHj_5yy3.js → list-DtEjqlED.js} +1 -1
  124. package/web/assets/{list-D-I0msRW.js → list-O_uCSLFq.js} +2 -2
  125. package/web/assets/{list-1OG83xc4.js → list-YNWVqjwW.js} +1 -1
  126. package/web/assets/{list-CNmzJKIQ.js → list-ZaBapEXW.js} +1 -1
  127. package/web/assets/metadata-_hV0ZaVh.js +55 -0
  128. package/web/assets/{meter-event-lmNMgmIu.js → meter-event-CPVBpekF.js} +1 -1
  129. package/web/assets/{metrics-C7U41HWk.js → metrics-DVPdwpyf.js} +1 -1
  130. package/web/assets/{overview-Cs3-8n4e.js → overview-CGdVIJrJ.js} +1 -1
  131. package/web/assets/{overview-CH1HnSP-.js → overview-CN59I5Sc.js} +1 -1
  132. package/web/assets/{past-due-CGGRZmXY.js → past-due-C3PtU8uo.js} +1 -1
  133. package/web/assets/pay-XVdSNq__.js +4 -0
  134. package/web/assets/{payment-method-info-BsOBbA3m.js → payment-method-info-D_qR04xC.js} +2 -2
  135. package/web/assets/{preview-CjYh9dTg.js → preview-Bdtbh-xk.js} +1 -1
  136. package/web/assets/{preview-DjYRpRA8.js → preview-F3lma170.js} +1 -1
  137. package/web/assets/{pricing-table-edE6TJGX.js → pricing-table-Bt2WljzE.js} +1 -1
  138. package/web/assets/{pricing-table-C3Lkhq46.js → pricing-table-D9FGYBVa.js} +2 -2
  139. package/web/assets/{product-select-0ScZE2e8.js → product-select-_72p-5lF.js} +1 -1
  140. package/web/assets/{recharge-DcPtT8vt.js → recharge-CSlKshbU.js} +1 -1
  141. package/web/assets/{related-credit-grants-BygNGPfb.js → related-credit-grants-DnKdAit6.js} +22 -22
  142. package/web/assets/{safe-did-address-B0fFbUph.js → safe-did-address-CRTPYo34.js} +1 -1
  143. package/web/assets/{source-data-viewer-By_Utay-.js → source-data-viewer-D1GShrs5.js} +1 -1
  144. package/web/assets/{status-l6pD08fw.js → status-3Swm2gK5.js} +1 -1
  145. package/web/assets/subscription-BX00k6FU.js +1 -0
  146. package/web/assets/{subscription-Dq22e3D1.js → subscription-Bzeblscr.js} +1 -1
  147. package/web/assets/table-BN3WBnr3.js +1 -0
  148. package/web/assets/{tax-code-select-CWhIIiXi.js → tax-code-select-j2arPbaE.js} +1 -1
  149. package/web/assets/{tax-utils-DqNX34-r.js → tax-utils-B8J0Kfnz.js} +1 -1
  150. package/web/assets/{uploader-DRXDz_r0.js → uploader-BLdAbLR6.js} +1 -1
  151. package/web/assets/{usage-records-jjJMZ6DI.js → usage-records-BAwNs1y8.js} +1 -1
  152. package/web/assets/{util-mDHAL0lx.js → util-B8B3fsMa.js} +1 -1
  153. package/web/assets/{vendor-arcblock-ChFCRdyx.js → vendor-arcblock-D1drrE7q.js} +1 -1
  154. package/web/assets/{vendor-blocklet-D_i_QeSo.js → vendor-blocklet-B67R14so.js} +43 -43
  155. package/web/index.html +1 -1
  156. package/web/assets/browser-DSLTxXlL.js +0 -1
  157. package/web/assets/detail-15zxCbV9.js +0 -10
  158. package/web/assets/detail-ASPdMJoW.js +0 -1
  159. package/web/assets/detail-CIx9vkir.js +0 -1
  160. package/web/assets/detail-D5NbV29V.js +0 -1
  161. package/web/assets/detail-DE3OOC5M.js +0 -15
  162. package/web/assets/detail-DVVzYhdV.js +0 -1
  163. package/web/assets/detail-Dqc0OfCQ.js +0 -1
  164. package/web/assets/detail-OZeeKI69.js +0 -24
  165. package/web/assets/detail-uhlID8jD.js +0 -15
  166. package/web/assets/form-BXAuSawq.js +0 -9
  167. package/web/assets/form-CKfKLGXP.js +0 -16
  168. package/web/assets/index-0HK7CYm4.js +0 -1
  169. package/web/assets/index-BJ_E6bEO.js +0 -1
  170. package/web/assets/index-Bnyh4rlV.js +0 -1
  171. package/web/assets/index-BoQ7wf3O.js +0 -1
  172. package/web/assets/index-C68x-aau.js +0 -1
  173. package/web/assets/index-C8s2QKoe.js +0 -1
  174. package/web/assets/index-Cn7O-OP7.js +0 -49
  175. package/web/assets/index-DU39aG5u.js +0 -1
  176. package/web/assets/index-DtbqgSK4.js +0 -1
  177. package/web/assets/index-DuRu9NWB.js +0 -14
  178. package/web/assets/index-WMKOiUez.js +0 -1
  179. package/web/assets/index-dmHgoplS.js +0 -1
  180. package/web/assets/index-txVTkoDD.js +0 -1
  181. package/web/assets/metadata-CMSHcSXi.js +0 -55
  182. package/web/assets/pay-CSpHBUh_.js +0 -4
  183. package/web/assets/subscription-DcwhSOpa.js +0 -1
  184. package/web/assets/table-BRU4Enia.js +0 -1
package/dist/index.js CHANGED
@@ -410,6 +410,7 @@ __export(env_exports, {
410
410
  stripePaymentCronTime: () => stripePaymentCronTime,
411
411
  stripeSubscriptionCronTime: () => stripeSubscriptionCronTime,
412
412
  stripeWebhookSecret: () => stripeWebhookSecret,
413
+ stripeWebhookUrl: () => stripeWebhookUrl,
413
414
  subscriptionCronTime: () => subscriptionCronTime,
414
415
  systemMaxPendingAmount: () => systemMaxPendingAmount,
415
416
  tenantModeRaw: () => tenantModeRaw,
@@ -436,7 +437,7 @@ function hasConfig(key) {
436
437
  const v = readConfig(key);
437
438
  return v !== void 0 && v !== "";
438
439
  }
439
- var import_env, activeConfig, numConfig, TRUTHY, FALSY, parseBool, readConfigAny, paymentStatCronTime, subscriptionCronTime, notificationCronTime, expiredSessionCleanupCronTime, notificationCronConcurrency, stripeInvoiceCronTime, stripePaymentCronTime, stripeSubscriptionCronTime, revokeStakeCronTime, meteringSubscriptionDetectionCronTime, overdueDetectionCronTime, overdueThreshold, depositVaultCronTime, creditConsumptionCronTime, vendorStatusCheckCronTime, vendorReturnScanCronTime, iapReconcileCronTime, eventRetryCronTime, quoteCleanupCronTime, vendorTimeoutMinutes, webhookAlertWindowMinutes, webhookAlertMinFailures, shortUrlApiKey, shortUrlDomain, sequelizeOptionsPoolMin, sequelizeOptionsPoolMax, sequelizeOptionsPoolIdle, updateDataConcurrency, stopAcceptingOrders, exchangeRateCacheTTLSeconds, systemMaxPendingAmount, allowChangeLockedPrice, blockletMode, isProduction, nodeEnv, isTestEnv, isDevelopmentEnv, enableDevFakeAuth, tenantModeRaw, blockletAppPid, blockletAppId, blockletAppName, blockletAppUrl, blockletAppHost, blockletAppDir, blockletPort, blockletMountPoints, appStoreWriteEnabled, appStoreSkipSignatureVerify, googlePubsubSkipSignatureVerify, googlePubsubPushServiceAccount, googlePubsubAllowUnverifiedSender, googlePlayWebhookUrl, stripeWebhookSecret, iapReconcileBatchSize, paymentBillingThreshold, paymentMinStakeAmount, paymentDaysUntilDue, paymentDaysUntilCancel, paymentReloadSubscriptionJobs, paymentRateVolatilityThreshold, paymentLivemode, creditLowBalanceThresholdPercentage, creditBatchSize, creditBatchWindowMs, creditQueueConcurrency, exchangeRateCacheTTLFromEnv, sqlLog, sqlBenchmark, cfEnv, isCfWorker, isBlockletServer, env_default;
440
+ var import_env, activeConfig, numConfig, TRUTHY, FALSY, parseBool, readConfigAny, paymentStatCronTime, subscriptionCronTime, notificationCronTime, expiredSessionCleanupCronTime, notificationCronConcurrency, stripeInvoiceCronTime, stripePaymentCronTime, stripeSubscriptionCronTime, revokeStakeCronTime, meteringSubscriptionDetectionCronTime, overdueDetectionCronTime, overdueThreshold, depositVaultCronTime, creditConsumptionCronTime, vendorStatusCheckCronTime, vendorReturnScanCronTime, iapReconcileCronTime, eventRetryCronTime, quoteCleanupCronTime, vendorTimeoutMinutes, webhookAlertWindowMinutes, webhookAlertMinFailures, shortUrlApiKey, shortUrlDomain, sequelizeOptionsPoolMin, sequelizeOptionsPoolMax, sequelizeOptionsPoolIdle, updateDataConcurrency, stopAcceptingOrders, exchangeRateCacheTTLSeconds, systemMaxPendingAmount, allowChangeLockedPrice, blockletMode, isProduction, nodeEnv, isTestEnv, isDevelopmentEnv, enableDevFakeAuth, tenantModeRaw, blockletAppPid, blockletAppId, blockletAppName, blockletAppUrl, blockletAppHost, blockletAppDir, blockletPort, blockletMountPoints, appStoreWriteEnabled, appStoreSkipSignatureVerify, googlePubsubSkipSignatureVerify, googlePubsubPushServiceAccount, googlePubsubAllowUnverifiedSender, googlePlayWebhookUrl, stripeWebhookSecret, stripeWebhookUrl, iapReconcileBatchSize, paymentBillingThreshold, paymentMinStakeAmount, paymentDaysUntilDue, paymentDaysUntilCancel, paymentReloadSubscriptionJobs, paymentRateVolatilityThreshold, paymentLivemode, creditLowBalanceThresholdPercentage, creditBatchSize, creditBatchWindowMs, creditQueueConcurrency, exchangeRateCacheTTLFromEnv, sqlLog, sqlBenchmark, cfEnv, isCfWorker, isBlockletServer, env_default;
440
441
  var init_env = __esm({
441
442
  "../../blocklets/core/api/src/libs/env.ts"() {
442
443
  "use strict";
@@ -518,6 +519,7 @@ var init_env = __esm({
518
519
  googlePubsubAllowUnverifiedSender = () => parseBool(readConfig("GOOGLE_PUBSUB_ALLOW_UNVERIFIED_SENDER"));
519
520
  googlePlayWebhookUrl = () => readConfig("GOOGLE_PLAY_WEBHOOK_URL");
520
521
  stripeWebhookSecret = () => readConfig("STRIPE_WEBHOOK_SECRET");
522
+ stripeWebhookUrl = () => readConfig("STRIPE_WEBHOOK_URL");
521
523
  iapReconcileBatchSize = () => Number(readConfig("IAP_RECONCILE_BATCH_SIZE") ?? "100");
522
524
  paymentBillingThreshold = () => +readConfig("PAYMENT_BILLING_THRESHOLD");
523
525
  paymentMinStakeAmount = () => +readConfig("PAYMENT_MIN_STAKE_AMOUNT");
@@ -1132,6 +1134,10 @@ var init_context = __esm({
1132
1134
  peekInstanceDid() {
1133
1135
  return this.storage.getStore()?.instanceDid;
1134
1136
  }
1137
+ /** Request-scoped externally reachable payment base URL, when supplied by an embedded host. */
1138
+ peekPublicBaseUrl() {
1139
+ return this.storage.getStore()?.publicBaseUrl;
1140
+ }
1135
1141
  /**
1136
1142
  * Run fn as a system operation: TenantModel scoping is bypassed for the span
1137
1143
  * of fn so legitimate cross-tenant reads can load rows regardless of tenant.
@@ -1149,13 +1155,15 @@ var init_context = __esm({
1149
1155
  run(context2, fn3) {
1150
1156
  const requestId = context2.requestId || `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
1151
1157
  const instanceDid = context2.instanceDid ?? this.storage.getStore()?.instanceDid;
1158
+ const publicBaseUrl = context2.publicBaseUrl ?? this.storage.getStore()?.publicBaseUrl;
1152
1159
  this.contexts.set(requestId, {
1153
1160
  ...context2,
1154
1161
  instanceDid,
1162
+ publicBaseUrl,
1155
1163
  requestId
1156
1164
  });
1157
1165
  return new Promise((resolve, reject) => {
1158
- this.storage.run({ ...context2, instanceDid, requestId }, async () => {
1166
+ this.storage.run({ ...context2, instanceDid, publicBaseUrl, requestId }, async () => {
1159
1167
  const resource = new import_async_hooks.AsyncResource("RequestContext");
1160
1168
  try {
1161
1169
  const result = await resource.runInAsyncScope(fn3);
@@ -1203,6 +1211,24 @@ var init_logger = __esm({
1203
1211
  }
1204
1212
  });
1205
1213
 
1214
+ // ../../blocklets/core/api/src/libs/secrets.ts
1215
+ function encryptSecret(value) {
1216
+ return getSecretsDriver().encryptSync(getInstanceDid(), value);
1217
+ }
1218
+ function decryptSecret(value) {
1219
+ return getSecretsDriver().decryptSync(getInstanceDid(), value);
1220
+ }
1221
+ function warmupSecrets(instanceDid) {
1222
+ return getSecretsDriver().warmup(instanceDid ?? getInstanceDid());
1223
+ }
1224
+ var init_secrets2 = __esm({
1225
+ "../../blocklets/core/api/src/libs/secrets.ts"() {
1226
+ "use strict";
1227
+ init_context();
1228
+ init_secrets();
1229
+ }
1230
+ });
1231
+
1206
1232
  // ../../blocklets/core/api/src/libs/did-connect/tenant-identity.ts
1207
1233
  var tenant_identity_exports = {};
1208
1234
  __export(tenant_identity_exports, {
@@ -1274,7 +1300,14 @@ async function warmTenantIdentity(instanceDidArg) {
1274
1300
  try {
1275
1301
  await resolveTenantIdentity(instanceDidArg);
1276
1302
  } catch (err) {
1277
- logger_default.warn("[tenant-identity] warm failed \u2014 wallet access will fail-closed", {
1303
+ logger_default.warn("[tenant-identity] wallet identity warm failed \u2014 wallet access will fail-closed", {
1304
+ error: err instanceof Error ? err.message : String(err)
1305
+ });
1306
+ }
1307
+ try {
1308
+ await warmupSecrets(instanceDidArg);
1309
+ } catch (err) {
1310
+ logger_default.warn("[tenant-identity] secrets warm failed \u2014 settings/Stripe decrypt will fail-closed", {
1278
1311
  error: err instanceof Error ? err.message : String(err)
1279
1312
  });
1280
1313
  }
@@ -1299,6 +1332,7 @@ var init_tenant_identity = __esm({
1299
1332
  init_context();
1300
1333
  init_drivers();
1301
1334
  init_logger();
1335
+ init_secrets2();
1302
1336
  walletType = {
1303
1337
  role: Mcrypto.types.RoleType.ROLE_APPLICATION,
1304
1338
  pk: Mcrypto.types.KeyType.ED25519,
@@ -1773,6 +1807,13 @@ var init_auth = __esm({
1773
1807
  });
1774
1808
 
1775
1809
  // ../../blocklets/core/api/src/libs/util.ts
1810
+ function getPublicAssetUrl(assetUrl) {
1811
+ if (!assetUrl || !assetUrl.startsWith("/") || assetUrl.startsWith("//")) return assetUrl;
1812
+ const basePath = readConfig("PAYMENT_PUBLIC_BASE_PATH");
1813
+ if (!basePath) return (0, import_component.getUrl)(assetUrl);
1814
+ if (assetUrl === basePath || assetUrl.startsWith(`${basePath}/`)) return assetUrl;
1815
+ return (0, import_ufo.joinURL)(basePath, assetUrl);
1816
+ }
1776
1817
  function md5(input) {
1777
1818
  return import_crypto2.default.createHash("md5").update(input).digest("hex");
1778
1819
  }
@@ -2197,7 +2238,7 @@ function formatLinkWithLocale(url, locale) {
2197
2238
  return `${url}${separator}locale=${locale}`;
2198
2239
  }
2199
2240
  }
2200
- var import_crypto2, import_stream, import_consumers, import_component, import_env4, import_did, import_cbor, import_nanoid, import_ufo, import_axios, import_util, import_get, import_trimEnd, OCAP_PAYMENT_TX_TYPE, MAX_SUBSCRIPTION_ITEM_COUNT, MAX_RETRY_COUNT, MIN_RETRY_MAIL, CHECKOUT_SESSION_TTL, STRIPE_API_VERSION, STRIPE_ENDPOINT, googlePlayEndpoint, GOOGLE_PLAY_ENDPOINT, APP_STORE_ENDPOINT, STRIPE_EVENTS, api, getNextRetry, getWebhookJobId, cachedBlockletJsonResult, CACHE_TTL, CURRENCY_SYMBOLS;
2241
+ var import_crypto2, import_stream, import_consumers, import_component, import_env4, import_did, import_cbor, import_nanoid, import_ufo, import_axios, import_util, import_get, import_trimEnd, OCAP_PAYMENT_TX_TYPE, MAX_SUBSCRIPTION_ITEM_COUNT, MAX_RETRY_COUNT, MIN_RETRY_MAIL, CHECKOUT_SESSION_TTL, STRIPE_API_VERSION, stripeEndpoint, googlePlayEndpoint, GOOGLE_PLAY_ENDPOINT, APP_STORE_ENDPOINT, STRIPE_EVENTS, api, getNextRetry, getWebhookJobId, cachedBlockletJsonResult, CACHE_TTL, CURRENCY_SYMBOLS;
2201
2242
  var init_util = __esm({
2202
2243
  "../../blocklets/core/api/src/libs/util.ts"() {
2203
2244
  "use strict";
@@ -2215,6 +2256,7 @@ var init_util = __esm({
2215
2256
  import_get = __toESM(require("lodash/get"));
2216
2257
  import_trimEnd = __toESM(require("lodash/trimEnd"));
2217
2258
  init_env();
2259
+ init_context();
2218
2260
  init_dayjs();
2219
2261
  init_auth();
2220
2262
  init_logger();
@@ -2224,7 +2266,13 @@ var init_util = __esm({
2224
2266
  MIN_RETRY_MAIL = 13;
2225
2267
  CHECKOUT_SESSION_TTL = 6 * 60 * 60;
2226
2268
  STRIPE_API_VERSION = "2023-08-16";
2227
- STRIPE_ENDPOINT = (0, import_component.getUrl)("/api/integrations/stripe/webhook");
2269
+ stripeEndpoint = () => {
2270
+ const override = stripeWebhookUrl();
2271
+ if (override) return override;
2272
+ const publicBaseUrl = context.peekPublicBaseUrl();
2273
+ if (publicBaseUrl) return (0, import_ufo.joinURL)(publicBaseUrl, "/api/integrations/stripe/webhook");
2274
+ return (0, import_component.getUrl)("/api/integrations/stripe/webhook");
2275
+ };
2228
2276
  googlePlayEndpoint = () => googlePlayWebhookUrl() || (0, import_component.getUrl)("/api/integrations/google-play/webhook");
2229
2277
  GOOGLE_PLAY_ENDPOINT = googlePlayEndpoint();
2230
2278
  APP_STORE_ENDPOINT = (0, import_component.getUrl)("/api/integrations/app-store/webhook");
@@ -2314,6 +2362,11 @@ var init_payment_currency = __esm({
2314
2362
  init_util();
2315
2363
  nextId = createIdGenerator("pc", 12);
2316
2364
  PaymentCurrency = class _PaymentCurrency extends TenantModel {
2365
+ toJSON() {
2366
+ const data = super.toJSON();
2367
+ if (data.logo) data.logo = getPublicAssetUrl(data.logo);
2368
+ return data;
2369
+ }
2317
2370
  static {
2318
2371
  this.GENESIS_ATTRIBUTES = {
2319
2372
  id: {
@@ -6589,6 +6642,23 @@ var init_customer = __esm({
6589
6642
  });
6590
6643
 
6591
6644
  // ../../blocklets/core/api/src/middlewares/hono/security.ts
6645
+ function stripDidPrefix(did) {
6646
+ if (!did) return "";
6647
+ return did.startsWith("did:abt:") ? did.slice("did:abt:".length) : did;
6648
+ }
6649
+ function isSameDid(a, b) {
6650
+ const x = stripDidPrefix(a);
6651
+ const y = stripDidPrefix(b);
6652
+ return !!x && x === y;
6653
+ }
6654
+ async function findCustomerByEitherDid(did) {
6655
+ if (!did) return null;
6656
+ const bare = stripDidPrefix(did);
6657
+ if (!bare) return null;
6658
+ const prefixed = `did:abt:${bare}`;
6659
+ const found = await Customer.findOne({ where: { did: [bare, prefixed] } });
6660
+ return found;
6661
+ }
6592
6662
  function authenticate({
6593
6663
  component: component4,
6594
6664
  roles,
@@ -6704,7 +6774,7 @@ function authenticate({
6704
6774
  return next();
6705
6775
  }
6706
6776
  if (mine) {
6707
- const customer = await Customer.findOne({ where: { did: user4.did } });
6777
+ const customer = await findCustomerByEitherDid(user4.did);
6708
6778
  if (customer) {
6709
6779
  c.set("customer", customer);
6710
6780
  c.set("customer_id", customer.id);
@@ -6716,7 +6786,7 @@ function authenticate({
6716
6786
  const id = c.req.param("id");
6717
6787
  const doc = findById && typeof findById === "function" ? await findById(id) : await model.findByPk(id);
6718
6788
  if (doc && doc[field]) {
6719
- const customer = await Customer.findOne({ where: { did: user4.did } });
6789
+ const customer = await findCustomerByEitherDid(user4.did);
6720
6790
  c.set("doc", doc);
6721
6791
  c.set("customer", customer);
6722
6792
  if (customer && customer.id === doc[field]) {
@@ -9126,21 +9196,6 @@ var init_payment_link = __esm({
9126
9196
  }
9127
9197
  });
9128
9198
 
9129
- // ../../blocklets/core/api/src/libs/secrets.ts
9130
- function encryptSecret(value) {
9131
- return getSecretsDriver().encryptSync(getInstanceDid(), value);
9132
- }
9133
- function decryptSecret(value) {
9134
- return getSecretsDriver().decryptSync(getInstanceDid(), value);
9135
- }
9136
- var init_secrets2 = __esm({
9137
- "../../blocklets/core/api/src/libs/secrets.ts"() {
9138
- "use strict";
9139
- init_context();
9140
- init_secrets();
9141
- }
9142
- });
9143
-
9144
9199
  // ../../blocklets/core/api/src/integrations/app-store/apple-root-certs.ts
9145
9200
  var APPLE_INC_ROOT_B64, APPLE_ROOT_CA_G2_B64, APPLE_ROOT_CA_G3_B64, APPLE_ROOT_CERTS;
9146
9201
  var init_apple_root_certs = __esm({
@@ -9416,7 +9471,7 @@ function decodeUnsafe(jws) {
9416
9471
  throw new Error(`AppStore JWS payload not valid JSON: ${err.message}`);
9417
9472
  }
9418
9473
  }
9419
- async function getAllSubscriptionStatuses(originalTransactionId, creds) {
9474
+ function getAllSubscriptionStatuses(originalTransactionId, creds) {
9420
9475
  return nativeGetAllSubscriptionStatuses(originalTransactionId, creds);
9421
9476
  }
9422
9477
  var init_signed_data_verifier = __esm({
@@ -9983,6 +10038,11 @@ var init_payment_method = __esm({
9983
10038
  googlePlayClients = /* @__PURE__ */ new Map();
9984
10039
  appStoreClients = /* @__PURE__ */ new Map();
9985
10040
  PaymentMethod = class _PaymentMethod extends TenantModel {
10041
+ toJSON() {
10042
+ const data = super.toJSON();
10043
+ if (data.logo) data.logo = getPublicAssetUrl(data.logo);
10044
+ return data;
10045
+ }
9986
10046
  static {
9987
10047
  this.GENESIS_ATTRIBUTES = {
9988
10048
  id: {
@@ -10078,11 +10138,13 @@ var init_payment_method = __esm({
10078
10138
  }
10079
10139
  static encryptSettings(settings) {
10080
10140
  const tmp = (0, import_cloneDeep3.default)(settings);
10081
- if (tmp.stripe) {
10141
+ if (tmp.stripe?.secret_key) {
10082
10142
  tmp.stripe.secret_key = encryptSecret(tmp.stripe.secret_key);
10143
+ }
10144
+ if (tmp.stripe?.webhook_signing_secret) {
10083
10145
  tmp.stripe.webhook_signing_secret = encryptSecret(tmp.stripe.webhook_signing_secret);
10084
10146
  }
10085
- if (tmp.google_play) {
10147
+ if (tmp.google_play?.service_account_json) {
10086
10148
  tmp.google_play.service_account_json = encryptSecret(tmp.google_play.service_account_json);
10087
10149
  }
10088
10150
  if (tmp.app_store?.private_key_pem) {
@@ -10095,11 +10157,13 @@ var init_payment_method = __esm({
10095
10157
  }
10096
10158
  static decryptSettings(settings) {
10097
10159
  const tmp = (0, import_cloneDeep3.default)(settings);
10098
- if (tmp.stripe) {
10160
+ if (tmp.stripe?.secret_key) {
10099
10161
  tmp.stripe.secret_key = decryptSecret(tmp.stripe.secret_key);
10162
+ }
10163
+ if (tmp.stripe?.webhook_signing_secret) {
10100
10164
  tmp.stripe.webhook_signing_secret = decryptSecret(tmp.stripe.webhook_signing_secret);
10101
10165
  }
10102
- if (tmp.google_play) {
10166
+ if (tmp.google_play?.service_account_json) {
10103
10167
  tmp.google_play.service_account_json = decryptSecret(tmp.google_play.service_account_json);
10104
10168
  }
10105
10169
  if (tmp.app_store?.private_key_pem) {
@@ -10145,7 +10209,7 @@ var init_payment_method = __esm({
10145
10209
  const host = this.settings.arcblock?.api_host;
10146
10210
  const cached = ocapClients.has(host);
10147
10211
  if (!cached) {
10148
- const created = new import_client.default(host);
10212
+ const created = new import_client.default(host, false);
10149
10213
  ocapClients.set(host, created);
10150
10214
  return created;
10151
10215
  }
@@ -15924,6 +15988,18 @@ function sessionMiddleware(options = {}) {
15924
15988
  } catch (err) {
15925
15989
  return c.json({ error: err.message }, 401);
15926
15990
  }
15991
+ if (!result) {
15992
+ const injectedDid = c.req.header("x-user-did");
15993
+ if (injectedDid) {
15994
+ result = {
15995
+ did: injectedDid,
15996
+ role: c.req.header("x-user-role"),
15997
+ provider: c.req.header("x-user-provider"),
15998
+ fullName: decodeURIComponent(c.req.header("x-user-fullname") || ""),
15999
+ walletOS: c.req.header("x-user-wallet-os") || ""
16000
+ };
16001
+ }
16002
+ }
15927
16003
  if (result) {
15928
16004
  c.set("user", result);
15929
16005
  }
@@ -22781,10 +22857,11 @@ __export(notification_exports, {
22781
22857
  ensureBlockletSdkTransportGuard: () => ensureBlockletSdkTransportGuard
22782
22858
  });
22783
22859
  function noopSdkTransport(mod, fns) {
22784
- const noop = async () => void 0;
22860
+ const noop = () => Promise.resolve(void 0);
22785
22861
  for (const target of [mod, mod?.default]) {
22786
- if (!target) continue;
22787
- for (const fn3 of fns) target[fn3] = noop;
22862
+ if (target) {
22863
+ for (const fn3 of fns) target[fn3] = noop;
22864
+ }
22788
22865
  }
22789
22866
  }
22790
22867
  function ensureBlockletSdkTransportGuard() {
@@ -33771,7 +33848,7 @@ async function handleSubscriptionEvent(event, _) {
33771
33848
  if (["incomplete", "incomplete_expired"].includes(subscription.status)) {
33772
33849
  logger_default.warn("subscription not ended on stripe event", { id: subscription.id });
33773
33850
  } else {
33774
- await subscription.update({ status: "canceled", ended_at: event.data.object.ended_at });
33851
+ await subscription.update({ status: "canceled", end_at: event.data.object.ended_at });
33775
33852
  logger_default.info("subscription ended on stripe event", { id: subscription.id });
33776
33853
  }
33777
33854
  }
@@ -34424,7 +34501,8 @@ async function handleStripePaymentSucceed(paymentIntent, event) {
34424
34501
  await handlePaymentSucceed(paymentIntent, triggerRenew);
34425
34502
  }
34426
34503
  async function syncStripePayment(paymentIntent) {
34427
- if (!paymentIntent?.metadata?.stripe_id) {
34504
+ const stripePaymentIntentId = paymentIntent?.payment_details?.stripe?.payment_intent_id || paymentIntent?.metadata?.stripe_id;
34505
+ if (!stripePaymentIntentId) {
34428
34506
  return;
34429
34507
  }
34430
34508
  const method = await PaymentMethod.findByPk(paymentIntent.payment_method_id);
@@ -34433,7 +34511,7 @@ async function syncStripePayment(paymentIntent) {
34433
34511
  }
34434
34512
  const triggerRenew = paymentIntent.status !== "succeeded";
34435
34513
  const client = await method.getStripeClient();
34436
- const stripeIntent = await client.paymentIntents.retrieve(paymentIntent.metadata.stripe_id);
34514
+ const stripeIntent = await client.paymentIntents.retrieve(stripePaymentIntentId);
34437
34515
  if (stripeIntent) {
34438
34516
  await paymentIntent.update({
34439
34517
  amount: String(stripeIntent.amount),
@@ -42576,6 +42654,85 @@ var init_url = __esm({
42576
42654
  }
42577
42655
  });
42578
42656
 
42657
+ // ../../blocklets/core/api/src/integrations/stripe/reconcile-checkout-core.ts
42658
+ async function reconcileStripeCheckoutSessionWithDeps(sessionId, deps) {
42659
+ const checkoutSession = await deps.findCheckoutSession(sessionId);
42660
+ if (!checkoutSession) {
42661
+ throw new Error("Checkout session not found");
42662
+ }
42663
+ if (checkoutSession.status === "complete") {
42664
+ return {
42665
+ status: checkoutSession.status,
42666
+ paymentStatus: checkoutSession.payment_status,
42667
+ reconciled: false
42668
+ };
42669
+ }
42670
+ let reconciled = false;
42671
+ if (checkoutSession.payment_intent_id) {
42672
+ const paymentIntent = await deps.findPaymentIntent(checkoutSession.payment_intent_id);
42673
+ if (paymentIntent && paymentIntent.status !== "succeeded") {
42674
+ await deps.syncPayment(paymentIntent);
42675
+ reconciled = true;
42676
+ }
42677
+ }
42678
+ const subscriptionIds = deps.getSubscriptionIds(checkoutSession);
42679
+ if (subscriptionIds.length > 0) {
42680
+ const subscriptions = await deps.findSubscriptions(subscriptionIds);
42681
+ for (const subscription of subscriptions) {
42682
+ if (subscription.status === "incomplete") {
42683
+ await deps.syncSubscription(subscription);
42684
+ reconciled = true;
42685
+ }
42686
+ }
42687
+ }
42688
+ await checkoutSession.reload();
42689
+ return {
42690
+ status: checkoutSession.status,
42691
+ paymentStatus: checkoutSession.payment_status,
42692
+ reconciled
42693
+ };
42694
+ }
42695
+ var init_reconcile_checkout_core = __esm({
42696
+ "../../blocklets/core/api/src/integrations/stripe/reconcile-checkout-core.ts"() {
42697
+ "use strict";
42698
+ }
42699
+ });
42700
+
42701
+ // ../../blocklets/core/api/src/integrations/stripe/reconcile-checkout.ts
42702
+ async function syncSubscription(subscription) {
42703
+ if (!subscription.payment_details?.stripe?.subscription_id) return;
42704
+ const method = await PaymentMethod.findByPk(subscription.default_payment_method_id);
42705
+ if (!method || method.type !== "stripe") return;
42706
+ const remote = await method.getStripeClient().subscriptions.retrieve(subscription.payment_details.stripe.subscription_id, {
42707
+ expand: ["latest_invoice.payment_intent", "pending_setup_intent"]
42708
+ });
42709
+ if (["active", "trialing"].includes(remote.status)) {
42710
+ await handleStripeSubscriptionSucceed(subscription, remote.status);
42711
+ }
42712
+ }
42713
+ function reconcileStripeCheckoutSession(sessionId, deps = defaultDeps) {
42714
+ return reconcileStripeCheckoutSessionWithDeps(sessionId, deps);
42715
+ }
42716
+ var defaultDeps;
42717
+ var init_reconcile_checkout = __esm({
42718
+ "../../blocklets/core/api/src/integrations/stripe/reconcile-checkout.ts"() {
42719
+ "use strict";
42720
+ init_session2();
42721
+ init_models();
42722
+ init_payment_intent2();
42723
+ init_subscription3();
42724
+ init_reconcile_checkout_core();
42725
+ defaultDeps = {
42726
+ findCheckoutSession: (id) => CheckoutSession.findByPk(id),
42727
+ findPaymentIntent: (id) => PaymentIntent.findByPk(id),
42728
+ getSubscriptionIds: getCheckoutSessionSubscriptionIds,
42729
+ findSubscriptions: (ids) => Subscription.findAll({ where: { id: ids } }),
42730
+ syncPayment: syncStripePayment,
42731
+ syncSubscription
42732
+ };
42733
+ }
42734
+ });
42735
+
42579
42736
  // ../../blocklets/core/api/src/routes/hono/checkout-sessions.ts
42580
42737
  async function validateInventory(line_items, includePendingQuantity = false) {
42581
42738
  const checks = line_items.map((item) => async () => {
@@ -43921,6 +44078,7 @@ var init_checkout_sessions = __esm({
43921
44078
  init_token_address_mapping();
43922
44079
  init_sequelize();
43923
44080
  init_session();
44081
+ init_reconcile_checkout();
43924
44082
  app6 = new import_hono6.Hono();
43925
44083
  user2 = sessionMiddleware({ accessKey: true });
43926
44084
  auth6 = authenticate({ component: true, roles: ["owner", "admin"] });
@@ -44237,6 +44395,27 @@ var init_checkout_sessions = __esm({
44237
44395
  paymentIntent: piStatus
44238
44396
  });
44239
44397
  });
44398
+ app6.post("/:id/stripe-reconcile", user2, async (c) => {
44399
+ const currentUser = c.get("user");
44400
+ if (!currentUser) {
44401
+ return c.json({ error: "Unauthorized" }, 403);
44402
+ }
44403
+ const doc = await CheckoutSession.findByPk(c.req.param("id"), {
44404
+ attributes: ["id", "customer_did"]
44405
+ });
44406
+ if (!doc) {
44407
+ return c.json({ error: "Checkout session not found" }, 404);
44408
+ }
44409
+ if (!["owner", "admin"].includes(currentUser.role) && !isSameDid(doc.customer_did, currentUser.did)) {
44410
+ return c.json({ error: "Not authorized to reconcile this checkout session" }, 403);
44411
+ }
44412
+ try {
44413
+ return c.json(await reconcileStripeCheckoutSession(doc.id));
44414
+ } catch (err) {
44415
+ logger_default.error("stripe checkout reconciliation failed", { checkoutSessionId: doc.id, error: err });
44416
+ return c.json({ error: err.message }, 502);
44417
+ }
44418
+ });
44240
44419
  app6.get("/retrieve/:id", user2, async (c) => {
44241
44420
  const doc = await CheckoutSession.findByPk(c.req.param("id"));
44242
44421
  if (!doc) {
@@ -44725,21 +44904,23 @@ var init_checkout_sessions = __esm({
44725
44904
  invoice_prefix: Customer.getInvoicePrefix()
44726
44905
  });
44727
44906
  logger_default.info("customer created on checkout session submit", { did: c.get("user").did, id: customer.id });
44728
- try {
44729
- await blocklet.updateUserAddress(
44730
- {
44731
- did: customer.did,
44732
- address: Customer.formatAddressFromCustomer(customer)
44733
- },
44734
- {
44735
- headers: {
44736
- cookie: c.req.header("cookie") || ""
44907
+ if (isBlockletServer()) {
44908
+ try {
44909
+ await blocklet.updateUserAddress(
44910
+ {
44911
+ did: customer.did,
44912
+ address: Customer.formatAddressFromCustomer(customer)
44913
+ },
44914
+ {
44915
+ headers: {
44916
+ cookie: c.req.header("cookie") || ""
44917
+ }
44737
44918
  }
44738
- }
44739
- );
44740
- logger_default.info("updateUserAddress success", { did: customer.did });
44741
- } catch (err) {
44742
- logger_default.error("updateUserAddress failed", { error: err, customerId: customer.id });
44919
+ );
44920
+ logger_default.info("updateUserAddress success", { did: customer.did });
44921
+ } catch (err) {
44922
+ logger_default.error("updateUserAddress failed", { error: err, customerId: customer.id });
44923
+ }
44743
44924
  }
44744
44925
  } else {
44745
44926
  const updates = {};
@@ -44765,23 +44946,25 @@ var init_checkout_sessions = __esm({
44765
44946
  } else {
44766
44947
  await customer.update(updates);
44767
44948
  logger_default.info("customer updated", { did: customer.did });
44768
- try {
44769
- await blocklet.updateUserAddress(
44770
- {
44771
- did: customer.did,
44772
- address: Customer.formatAddressFromCustomer(customer),
44773
- // @ts-ignore
44774
- phone: customer.phone
44775
- },
44776
- {
44777
- headers: {
44778
- cookie: c.req.header("cookie") || ""
44949
+ if (isBlockletServer()) {
44950
+ try {
44951
+ await blocklet.updateUserAddress(
44952
+ {
44953
+ did: customer.did,
44954
+ address: Customer.formatAddressFromCustomer(customer),
44955
+ // @ts-ignore
44956
+ phone: customer.phone
44957
+ },
44958
+ {
44959
+ headers: {
44960
+ cookie: c.req.header("cookie") || ""
44961
+ }
44779
44962
  }
44780
- }
44781
- );
44782
- logger_default.info("updateUserAddress success", { did: customer.did });
44783
- } catch (err) {
44784
- logger_default.error("updateUserAddress failed", { error: err, customerId: customer.id });
44963
+ );
44964
+ logger_default.info("updateUserAddress success", { did: customer.did });
44965
+ } catch (err) {
44966
+ logger_default.error("updateUserAddress failed", { error: err, customerId: customer.id });
44967
+ }
44785
44968
  }
44786
44969
  }
44787
44970
  }
@@ -47455,7 +47638,7 @@ async function ensureWebhookRegistered() {
47455
47638
  const exist = data.find((webhook) => webhook.metadata?.appPid === import_env29.env.appPid);
47456
47639
  if (exist) {
47457
47640
  await stripe.webhookEndpoints.update(exist.id, {
47458
- url: STRIPE_ENDPOINT,
47641
+ url: stripeEndpoint(),
47459
47642
  description: import_env29.env.appName,
47460
47643
  enabled_events: STRIPE_EVENTS,
47461
47644
  disabled: false
@@ -47463,7 +47646,7 @@ async function ensureWebhookRegistered() {
47463
47646
  logger_default.info("stripe webhook updated");
47464
47647
  } else {
47465
47648
  const result = await stripe.webhookEndpoints.create({
47466
- url: STRIPE_ENDPOINT,
47649
+ url: stripeEndpoint(),
47467
47650
  description: import_env29.env.appName,
47468
47651
  enabled_events: STRIPE_EVENTS,
47469
47652
  api_version: STRIPE_API_VERSION,
@@ -47609,7 +47792,9 @@ var init_payment_methods = __esm({
47609
47792
  metadata: {}
47610
47793
  });
47611
47794
  await method.update({ default_currency_id: currency.id });
47612
- ensureWebhookRegistered().catch(console.error);
47795
+ ensureWebhookRegistered().catch(
47796
+ (err) => logger_default.error("ensureWebhookRegistered failed (payments may not reconcile in real-time)", err)
47797
+ );
47613
47798
  return c.json({ ...method.toJSON(), payment_currencies: [currency.toJSON()] });
47614
47799
  }
47615
47800
  if (EVM_CHAIN_TYPES.includes(raw.type)) {
@@ -47972,7 +48157,9 @@ var init_payment_methods = __esm({
47972
48157
  }
47973
48158
  const updatedMethod = await method.update(updateData);
47974
48159
  if (method.type === "stripe") {
47975
- ensureWebhookRegistered().catch(console.error);
48160
+ ensureWebhookRegistered().catch(
48161
+ (err) => logger_default.error("ensureWebhookRegistered failed (payments may not reconcile in real-time)", err)
48162
+ );
47976
48163
  }
47977
48164
  return c.json(updatedMethod);
47978
48165
  } catch (err) {
@@ -58442,12 +58629,14 @@ async function ingestVerifiedAppStorePurchase({
58442
58629
  }
58443
58630
  const newExpiresAt = transaction.expiresDate ? Math.floor(Number(transaction.expiresDate) / 1e3) : 0;
58444
58631
  const newTxnValid = !!newExpiresAt && newExpiresAt * 1e3 > Date.now();
58445
- const lapsed = ["canceled", "incomplete_expired", "past_due"].includes(existing.status);
58632
+ const storedExpiresAt = existing.current_period_end ?? 0;
58633
+ const storedExpired = !!storedExpiresAt && storedExpiresAt * 1e3 < Date.now();
58634
+ const lapsed = ["canceled", "incomplete_expired", "past_due"].includes(existing.status) || storedExpired;
58446
58635
  if (lapsed && newTxnValid) {
58447
58636
  const updatePatch = {
58448
58637
  status: "active",
58449
58638
  current_period_end: newExpiresAt,
58450
- ended_at: null,
58639
+ end_at: null,
58451
58640
  cancel_at_period_end: false,
58452
58641
  payment_details: {
58453
58642
  ...existing.payment_details || {},
@@ -58483,6 +58672,31 @@ async function ingestVerifiedAppStorePurchase({
58483
58672
  });
58484
58673
  return { subscription: existing, isFirstSubscribe: false, transaction };
58485
58674
  }
58675
+ if (lapsed && !newTxnValid) {
58676
+ await existing.update({
58677
+ status: "incomplete_expired",
58678
+ end_at: Math.floor(Date.now() / 1e3),
58679
+ cancel_at_period_end: false,
58680
+ payment_details: {
58681
+ ...existing.payment_details || {},
58682
+ app_store: {
58683
+ ...existing.payment_details?.app_store || {},
58684
+ transaction_id: transaction.transactionId,
58685
+ expires_at: newExpiresAt || existing.payment_details?.app_store?.expires_at
58686
+ }
58687
+ }
58688
+ });
58689
+ logger_default.info(
58690
+ "app_store verify: subscription fully lapsed (stored + replay both expired) \u2014 marked incomplete_expired",
58691
+ {
58692
+ subscriptionId: existing.id,
58693
+ originalTransactionId: transaction.originalTransactionId,
58694
+ storedExpiresAt,
58695
+ newExpiresAt
58696
+ }
58697
+ );
58698
+ return { subscription: existing, isFirstSubscribe: false, transaction };
58699
+ }
58486
58700
  const storedAppStoreSku = existing.payment_details?.app_store?.product_id;
58487
58701
  if (storedAppStoreSku && storedAppStoreSku !== transaction.productId) {
58488
58702
  const newPrice = await Price.findOne({
@@ -58800,7 +59014,7 @@ async function handleAppStoreRenewed(subscription, transaction) {
58800
59014
  }
58801
59015
  async function markAppStoreExpired(subscription) {
58802
59016
  if (["canceled", "incomplete_expired"].includes(subscription.status)) return;
58803
- await subscription.update({ status: "canceled", ended_at: Math.floor(Date.now() / 1e3) });
59017
+ await subscription.update({ status: "canceled", end_at: Math.floor(Date.now() / 1e3) });
58804
59018
  createEvent("Subscription", "customer.subscription.deleted", subscription).catch(reportAuditFailure);
58805
59019
  }
58806
59020
  async function markAppStorePastDue(subscription) {
@@ -58820,7 +59034,7 @@ async function handleAppStoreRevoked(subscription, notificationType, subtype) {
58820
59034
  const now = Math.floor(Date.now() / 1e3);
58821
59035
  await subscription.update({
58822
59036
  status: "canceled",
58823
- ended_at: now,
59037
+ end_at: now,
58824
59038
  cancelation_details: {
58825
59039
  ...subscription.cancelation_details ?? { comment: "", feedback: "other" },
58826
59040
  reason: "cancellation_requested"
@@ -59451,7 +59665,7 @@ async function handleRevoked(subscription) {
59451
59665
  const now = Math.floor(Date.now() / 1e3);
59452
59666
  await subscription.update({
59453
59667
  status: "canceled",
59454
- ended_at: now,
59668
+ end_at: now,
59455
59669
  cancelation_details: {
59456
59670
  ...subscription.cancelation_details ?? { comment: "", feedback: "other" },
59457
59671
  reason: "cancellation_requested"
@@ -59527,7 +59741,7 @@ async function handleGooglePlayVoidedPurchase({
59527
59741
  if (subscription.status !== "canceled" && subscription.status !== "incomplete_expired") {
59528
59742
  await subscription.update({
59529
59743
  status: "canceled",
59530
- ended_at: Math.floor(Date.now() / 1e3),
59744
+ end_at: Math.floor(Date.now() / 1e3),
59531
59745
  cancelation_details: {
59532
59746
  ...subscription.cancelation_details ?? { comment: "", feedback: "other" },
59533
59747
  reason: "cancellation_requested"
@@ -60682,7 +60896,8 @@ async function checkEntitlement({
60682
60896
  channel: await inferChannelFromSubscription(best),
60683
60897
  expires_at: best.current_period_end ?? null,
60684
60898
  subscription_id: best.id,
60685
- source: "subscription"
60899
+ source: "subscription",
60900
+ cancel_at_period_end: !!best.cancel_at_period_end
60686
60901
  };
60687
60902
  }
60688
60903
  const grant = await findGrantCoveringProduct(customer, product_id);
@@ -60764,7 +60979,8 @@ async function listEntitlements({
60764
60979
  channel: await inferChannelFromSubscription(best),
60765
60980
  expires_at: best.current_period_end ?? null,
60766
60981
  subscription_id: best.id,
60767
- source: "subscription"
60982
+ source: "subscription",
60983
+ cancel_at_period_end: !!best.cancel_at_period_end
60768
60984
  };
60769
60985
  return item;
60770
60986
  })
@@ -60846,7 +61062,7 @@ var init_entitlements = __esm({
60846
61062
  init_logger();
60847
61063
  init_security();
60848
61064
  app26 = new import_hono26.Hono();
60849
- auth18 = authenticate({ component: true, roles: ["owner", "admin"], ensureLogin: true });
61065
+ auth18 = authenticate({ component: true, ensureLogin: true });
60850
61066
  checkQuerySchema = import_joi25.default.object({
60851
61067
  customer_did: import_joi25.default.string().required(),
60852
61068
  product_id: import_joi25.default.string().required(),
@@ -67618,6 +67834,29 @@ var init_collect_batch = __esm({
67618
67834
  }
67619
67835
  });
67620
67836
 
67837
+ // ../../blocklets/core/api/src/libs/arcblock-transfer.ts
67838
+ async function encodeArcblockTransfer({
67839
+ chainHost,
67840
+ tx,
67841
+ wallet: wallet2
67842
+ }) {
67843
+ const context2 = await (0, import_encode.fetchContext)(chainHost);
67844
+ return (0, import_encode.encodeTx)({
67845
+ type: "TransferV3Tx",
67846
+ tx,
67847
+ wallet: wallet2,
67848
+ chainId: context2.chainId,
67849
+ feeConfig: context2.txFee
67850
+ });
67851
+ }
67852
+ var import_encode;
67853
+ var init_arcblock_transfer = __esm({
67854
+ "../../blocklets/core/api/src/libs/arcblock-transfer.ts"() {
67855
+ "use strict";
67856
+ import_encode = require("@ocap/client/encode");
67857
+ }
67858
+ });
67859
+
67621
67860
  // ../../blocklets/core/api/src/libs/chain-error.ts
67622
67861
  function parseChainError(err) {
67623
67862
  const msg = err?.message ?? String(err);
@@ -67662,6 +67901,7 @@ var init_pay = __esm({
67662
67901
  init_token();
67663
67902
  init_tx();
67664
67903
  init_auth();
67904
+ init_arcblock_transfer();
67665
67905
  init_logger();
67666
67906
  init_chain_error();
67667
67907
  init_payment();
@@ -67769,20 +68009,30 @@ var init_pay = __esm({
67769
68009
  }
67770
68010
  if (paymentMethod.type === "arcblock") {
67771
68011
  try {
67772
- await paymentIntent.update({ status: "processing" });
67773
68012
  const client = paymentMethod.getOcapClient();
67774
68013
  const claim = claims.find((x) => x.type === "prepareTx");
67775
- await client.getContext();
67776
68014
  const tx = client.decodeTx(claim.finalTx);
67777
68015
  if (claim.delegator && claim.from) {
67778
68016
  tx.delegator = claim.delegator;
67779
68017
  tx.from = claim.from;
67780
68018
  }
67781
- const { buffer: buffer2 } = await client.encodeTransferV3Tx({ tx });
68019
+ const chainHost = paymentMethod.settings.arcblock?.api_host;
68020
+ if (!chainHost) {
68021
+ throw new Error("ArcBlock payment method API host is missing");
68022
+ }
68023
+ const signingWallet = (0, import_wallet5.fromAddress)(userDid);
68024
+ const { object: encodedTx, buffer: buffer2 } = await encodeArcblockTransfer({
68025
+ chainHost,
68026
+ tx,
68027
+ wallet: signingWallet
68028
+ });
68029
+ const gasPayerExtra = await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client);
68030
+ await paymentIntent.update({ status: "processing" });
67782
68031
  const txHash = await client.sendTransferV3Tx(
67783
- // @ts-ignore
67784
- { tx, wallet: (0, import_wallet5.fromAddress)(userDid) },
67785
- await getGasPayerExtra(buffer2, client.pickGasPayerHeaders(request), client)
68032
+ // Passing the already-encoded signature skips the client's timer-backed
68033
+ // encodeTransferV3Tx/getContext path in Cloudflare Workers.
68034
+ { tx: encodedTx, wallet: signingWallet, signature: encodedTx.signature },
68035
+ gasPayerExtra
67786
68036
  );
67787
68037
  const quoteValidation = await validateQuoteForPayment({
67788
68038
  checkoutSessionId: checkoutSession?.id,
@@ -77304,6 +77554,7 @@ function csrfSecret() {
77304
77554
  }
77305
77555
  function csrf() {
77306
77556
  return async (c, next) => {
77557
+ if (readConfig("PAYMENT_DISABLE_CSRF") === "true") return next();
77307
77558
  const method = c.req.method.toUpperCase();
77308
77559
  const loginToken = (0, import_cookie.getCookie)(c, "login_token");
77309
77560
  const existingCsrf = (0, import_cookie.getCookie)(c, "x-csrf-token");
@@ -77566,10 +77817,18 @@ function buildConnectRoutesHono() {
77566
77817
  const connectApp = new import_hono43.Hono();
77567
77818
  connectApp.use("*", async (c, next) => {
77568
77819
  const { context: requestCtx } = (init_context(), __toCommonJS(context_exports));
77569
- if (requestCtx.peekInstanceDid()) return next();
77820
+ const { warmTenantIdentity: warmTenantIdentity2 } = (init_tenant_identity(), __toCommonJS(tenant_identity_exports));
77821
+ const preResolved = requestCtx.peekInstanceDid();
77822
+ if (preResolved) {
77823
+ await warmTenantIdentity2(preResolved);
77824
+ return next();
77825
+ }
77570
77826
  const { resolveTenantForHost: resolveTenantForHost2 } = (init_identity(), __toCommonJS(identity_exports));
77571
77827
  const instanceDid = await resolveTenantForHost2(c.req.header("host"));
77572
- return requestCtx.withTenant(instanceDid, () => next());
77828
+ return requestCtx.withTenant(instanceDid, async () => {
77829
+ await warmTenantIdentity2(instanceDid);
77830
+ return next();
77831
+ });
77573
77832
  });
77574
77833
  for (const h of connectHandlerModules()) handlers2.attach(Object.assign({ app: connectApp }, h));
77575
77834
  return connectApp;
@@ -77661,8 +77920,20 @@ async function provisionTenant(instanceDid) {
77661
77920
  const { fromTokenToUnit: fromTokenToUnit31 } = require("@ocap/util");
77662
77921
  const { PaymentMethod: PaymentMethod3, PaymentCurrency: PaymentCurrency3 } = (init_models(), __toCommonJS(models_exports));
77663
77922
  const CHAINS = [
77664
- { chainId: "main", livemode: true, symbol: "ABT", label: "ArcBlock Main", contract: "z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD" },
77665
- { chainId: "beta", livemode: false, symbol: "TBA", label: "ArcBlock Beta", contract: "z35n6UoHSi9MED4uaQy6ozFgKPaZj2UKrurBG" }
77923
+ {
77924
+ chainId: "main",
77925
+ livemode: true,
77926
+ symbol: "ABT",
77927
+ label: "ArcBlock Main",
77928
+ contract: "z35nNRvYxBoHitx9yZ5ATS88psfShzPPBLxYD"
77929
+ },
77930
+ {
77931
+ chainId: "beta",
77932
+ livemode: false,
77933
+ symbol: "TBA",
77934
+ label: "ArcBlock Beta",
77935
+ contract: "z35n6UoHSi9MED4uaQy6ozFgKPaZj2UKrurBG"
77936
+ }
77666
77937
  ];
77667
77938
  await context.withTenant(instanceDid, async () => {
77668
77939
  const existing = await PaymentMethod3.findOne({ where: { type: "arcblock" } });