payment-kit 1.27.2 → 1.29.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.
Files changed (241) hide show
  1. package/__blocklet__.js +37 -0
  2. package/api/ocap-1.30-subpath-shims.d.ts +35 -0
  3. package/api/src/crons/index.ts +32 -0
  4. package/api/src/crons/metering-subscription-detection.ts +12 -14
  5. package/api/src/crons/overdue-detection.ts +51 -74
  6. package/api/src/crons/retry-pending-events.ts +58 -0
  7. package/api/src/integrations/app-store/apple-root-certs.ts +26 -0
  8. package/api/src/integrations/app-store/client.ts +369 -0
  9. package/api/src/integrations/app-store/handlers/index.ts +46 -0
  10. package/api/src/integrations/app-store/handlers/subscription.ts +635 -0
  11. package/api/src/integrations/app-store/node-apple-receipt-verify.d.ts +17 -0
  12. package/api/src/integrations/app-store/notification-routing.ts +18 -0
  13. package/api/src/integrations/app-store/signed-data-verifier.ts +150 -0
  14. package/api/src/integrations/arcblock/nft.ts +6 -2
  15. package/api/src/integrations/arcblock/stake.ts +3 -2
  16. package/api/src/integrations/arcblock/token.ts +4 -4
  17. package/api/src/integrations/blocklet/notification.ts +1 -1
  18. package/api/src/integrations/ethereum/tx.ts +29 -0
  19. package/api/src/integrations/google-play/client.ts +276 -0
  20. package/api/src/integrations/google-play/handlers/index.ts +69 -0
  21. package/api/src/integrations/google-play/handlers/subscription.ts +565 -0
  22. package/api/src/integrations/google-play/handlers/voided.ts +106 -0
  23. package/api/src/integrations/google-play/setup.ts +43 -0
  24. package/api/src/integrations/google-play/verify.ts +251 -0
  25. package/api/src/integrations/iap-reconcile.ts +415 -0
  26. package/api/src/integrations/stripe/handlers/invoice.ts +70 -53
  27. package/api/src/integrations/stripe/handlers/payment-intent.ts +8 -1
  28. package/api/src/integrations/stripe/resource.ts +8 -0
  29. package/api/src/libs/audit.ts +70 -24
  30. package/api/src/libs/auth.ts +49 -2
  31. package/api/src/libs/chain-error.ts +31 -0
  32. package/api/src/libs/entitlement.ts +399 -0
  33. package/api/src/libs/env.ts +2 -0
  34. package/api/src/libs/error.ts +15 -0
  35. package/api/src/libs/event.ts +42 -1
  36. package/api/src/libs/invoice.ts +69 -34
  37. package/api/src/libs/notification/template/customer-auto-recharge-daily-limit-exceeded.ts +1 -3
  38. package/api/src/libs/notification/template/customer-auto-recharge-failed.ts +1 -3
  39. package/api/src/libs/notification/template/customer-credit-grant-granted.ts +1 -3
  40. package/api/src/libs/notification/template/customer-credit-insufficient.ts +1 -3
  41. package/api/src/libs/notification/template/customer-credit-low-balance.ts +1 -3
  42. package/api/src/libs/notification/template/customer-revenue-succeeded.ts +1 -3
  43. package/api/src/libs/notification/template/customer-reward-succeeded.ts +1 -3
  44. package/api/src/libs/notification/template/one-time-payment-refund-succeeded.ts +1 -3
  45. package/api/src/libs/notification/template/one-time-payment-succeeded.ts +1 -3
  46. package/api/src/libs/notification/template/subscription-renew-failed.ts +1 -3
  47. package/api/src/libs/notification/template/subscription-slippage-exceeded.ts +1 -3
  48. package/api/src/libs/notification/template/subscription-slippage-warning.ts +1 -3
  49. package/api/src/libs/notification/template/subscription-succeeded.ts +1 -1
  50. package/api/src/libs/pagination.ts +14 -9
  51. package/api/src/libs/payment.ts +25 -10
  52. package/api/src/libs/security.ts +51 -0
  53. package/api/src/libs/session.ts +1 -1
  54. package/api/src/libs/subscription.ts +13 -1
  55. package/api/src/libs/timing.ts +35 -0
  56. package/api/src/libs/util.ts +29 -15
  57. package/api/src/libs/wallet-migration.ts +72 -53
  58. package/api/src/queues/auto-recharge.ts +1 -1
  59. package/api/src/queues/credit-consume.ts +94 -12
  60. package/api/src/queues/credit-grant.ts +4 -0
  61. package/api/src/queues/event.ts +39 -21
  62. package/api/src/queues/invoice.ts +1 -0
  63. package/api/src/queues/payment.ts +83 -15
  64. package/api/src/queues/refund.ts +84 -71
  65. package/api/src/queues/subscription.ts +1 -0
  66. package/api/src/queues/webhook.ts +12 -2
  67. package/api/src/routes/checkout-sessions.ts +82 -43
  68. package/api/src/routes/connect/change-payment.ts +2 -0
  69. package/api/src/routes/connect/change-plan.ts +2 -0
  70. package/api/src/routes/connect/pay.ts +12 -3
  71. package/api/src/routes/connect/setup.ts +3 -1
  72. package/api/src/routes/connect/shared.ts +52 -39
  73. package/api/src/routes/connect/subscribe.ts +4 -1
  74. package/api/src/routes/credit-grants.ts +25 -17
  75. package/api/src/routes/donations.ts +2 -2
  76. package/api/src/routes/entitlements.ts +105 -0
  77. package/api/src/routes/events.ts +2 -2
  78. package/api/src/routes/index.ts +12 -2
  79. package/api/src/routes/integrations/app-store.ts +267 -0
  80. package/api/src/routes/integrations/google-play.ts +324 -0
  81. package/api/src/routes/meter-events.ts +16 -6
  82. package/api/src/routes/payment-links.ts +1 -1
  83. package/api/src/routes/payment-methods.ts +131 -1
  84. package/api/src/routes/settings.ts +1 -1
  85. package/api/src/routes/tax-rates.ts +1 -1
  86. package/api/src/store/migrations/20260526-iap-foundation.ts +105 -0
  87. package/api/src/store/models/customer.ts +37 -1
  88. package/api/src/store/models/entitlement-grant.ts +118 -0
  89. package/api/src/store/models/entitlement-product.ts +48 -0
  90. package/api/src/store/models/entitlement.ts +86 -0
  91. package/api/src/store/models/index.ts +9 -0
  92. package/api/src/store/models/invoice.ts +20 -0
  93. package/api/src/store/models/payment-method.ts +66 -1
  94. package/api/src/store/models/price.ts +23 -14
  95. package/api/src/store/models/refund.ts +10 -0
  96. package/api/src/store/models/subscription.ts +14 -0
  97. package/api/src/store/models/types.ts +32 -0
  98. package/api/tests/integrations/app-store/client.spec.ts +335 -0
  99. package/api/tests/integrations/app-store/handlers.spec.ts +480 -0
  100. package/api/tests/integrations/app-store/notifications.spec.ts +381 -0
  101. package/api/tests/integrations/app-store/signed-data-verifier.spec.ts +72 -0
  102. package/api/tests/integrations/app-store/webhook-routing.spec.ts +27 -0
  103. package/api/tests/integrations/google-play/handlers.spec.ts +341 -0
  104. package/api/tests/integrations/google-play/verify.spec.ts +215 -0
  105. package/api/tests/integrations/iap-reconcile.spec.ts +237 -0
  106. package/api/tests/libs/entitlement.spec.ts +347 -0
  107. package/api/tests/libs/wallet-migration.spec.ts +4 -4
  108. package/api/tests/queues/credit-consume-batch.spec.ts +5 -2
  109. package/api/tests/queues/credit-consume.spec.ts +8 -4
  110. package/api/tests/routes/credit-grants.spec.ts +1 -0
  111. package/blocklet.yml +1 -1
  112. package/cloudflare/MIGRATION-CHALLENGES.md +676 -0
  113. package/cloudflare/MIGRATION-RUNBOOK.md +777 -0
  114. package/cloudflare/README.md +499 -0
  115. package/cloudflare/STAGING-MIGRATION-GUIDE.md +602 -0
  116. package/cloudflare/build.ts +151 -0
  117. package/cloudflare/did-connect-auth.ts +527 -0
  118. package/cloudflare/docs/2026-04-22-sdk-1.30.9-upgrade-retro.md +324 -0
  119. package/cloudflare/docs/2026-04-24-queue-ops-followup.md +218 -0
  120. package/cloudflare/docs/cf-queues-ops-alert-analysis.md +663 -0
  121. package/cloudflare/docs/cf-workers-local-dev-and-fixes.md +284 -0
  122. package/cloudflare/docs/cleanup-tasks-2026-05.md +62 -0
  123. package/cloudflare/docs/payment-kit-platform-analysis-2026-04-20.md +354 -0
  124. package/cloudflare/frontend-shims/buffer-polyfill.ts +9 -0
  125. package/cloudflare/frontend-shims/js-sdk.ts +43 -0
  126. package/cloudflare/frontend-shims/mime-types.ts +46 -0
  127. package/cloudflare/frontend-shims/session.ts +24 -0
  128. package/cloudflare/frontend-shims/vite-plugin-noop.ts +6 -0
  129. package/cloudflare/index.html +40 -0
  130. package/cloudflare/migrate-to-d1.js +252 -0
  131. package/cloudflare/migrations/0001_initial_schema.sql +82 -0
  132. package/cloudflare/migrations/0002_indexes.sql +75 -0
  133. package/cloudflare/migrations/0003_locks_and_constraints.sql +18 -0
  134. package/cloudflare/migrations/0004_iap_foundation.sql +72 -0
  135. package/cloudflare/migrations/0005_iap_tenant_backfill.sql +112 -0
  136. package/cloudflare/run-build.js +391 -0
  137. package/cloudflare/scripts/test-decrypt.js +102 -0
  138. package/cloudflare/shims/arcblock-ws.ts +20 -0
  139. package/cloudflare/shims/axios-http-adapter.ts +4 -0
  140. package/cloudflare/shims/axios-lite.ts +117 -0
  141. package/cloudflare/shims/blocklet-sdk/auth-service.ts +33 -0
  142. package/cloudflare/shims/blocklet-sdk/cdn.ts +3 -0
  143. package/cloudflare/shims/blocklet-sdk/component-api.ts +35 -0
  144. package/cloudflare/shims/blocklet-sdk/component.ts +18 -0
  145. package/cloudflare/shims/blocklet-sdk/config.ts +8 -0
  146. package/cloudflare/shims/blocklet-sdk/did.ts +14 -0
  147. package/cloudflare/shims/blocklet-sdk/env.ts +12 -0
  148. package/cloudflare/shims/blocklet-sdk/eventbus.ts +3 -0
  149. package/cloudflare/shims/blocklet-sdk/fallback.ts +3 -0
  150. package/cloudflare/shims/blocklet-sdk/index.ts +11 -0
  151. package/cloudflare/shims/blocklet-sdk/logger.ts +11 -0
  152. package/cloudflare/shims/blocklet-sdk/middlewares.ts +15 -0
  153. package/cloudflare/shims/blocklet-sdk/notification.ts +11 -0
  154. package/cloudflare/shims/blocklet-sdk/security.ts +53 -0
  155. package/cloudflare/shims/blocklet-sdk/session.ts +8 -0
  156. package/cloudflare/shims/blocklet-sdk/verify-session.ts +44 -0
  157. package/cloudflare/shims/blocklet-sdk/verify-sign.ts +38 -0
  158. package/cloudflare/shims/blocklet-sdk/wallet-authenticator.ts +3 -0
  159. package/cloudflare/shims/blocklet-sdk/wallet-handler.ts +6 -0
  160. package/cloudflare/shims/blocklet-sdk/wallet.ts +103 -0
  161. package/cloudflare/shims/cookie-parser.ts +3 -0
  162. package/cloudflare/shims/cors.ts +21 -0
  163. package/cloudflare/shims/cron.ts +189 -0
  164. package/cloudflare/shims/crypto-js-warn.ts +7 -0
  165. package/cloudflare/shims/did-space-js.ts +17 -0
  166. package/cloudflare/shims/did-space.ts +11 -0
  167. package/cloudflare/shims/error.ts +18 -0
  168. package/cloudflare/shims/express-compat/index.ts +80 -0
  169. package/cloudflare/shims/express-compat/types.ts +41 -0
  170. package/cloudflare/shims/fastq.ts +105 -0
  171. package/cloudflare/shims/lock.ts +115 -0
  172. package/cloudflare/shims/mime-types.ts +56 -0
  173. package/cloudflare/shims/nedb-storage.ts +9 -0
  174. package/cloudflare/shims/node-child-process.ts +9 -0
  175. package/cloudflare/shims/node-fs.ts +20 -0
  176. package/cloudflare/shims/node-http.ts +13 -0
  177. package/cloudflare/shims/node-https.ts +4 -0
  178. package/cloudflare/shims/node-misc.ts +15 -0
  179. package/cloudflare/shims/node-net.ts +8 -0
  180. package/cloudflare/shims/node-os.ts +14 -0
  181. package/cloudflare/shims/node-tty.ts +8 -0
  182. package/cloudflare/shims/node-zlib.ts +17 -0
  183. package/cloudflare/shims/noop.ts +26 -0
  184. package/cloudflare/shims/payment-vendor.ts +14 -0
  185. package/cloudflare/shims/querystring.ts +12 -0
  186. package/cloudflare/shims/queue.ts +611 -0
  187. package/cloudflare/shims/rolldown-runtime.ts +43 -0
  188. package/cloudflare/shims/sequelize-d1/datatypes.ts +24 -0
  189. package/cloudflare/shims/sequelize-d1/helpers.ts +46 -0
  190. package/cloudflare/shims/sequelize-d1/index.ts +34 -0
  191. package/cloudflare/shims/sequelize-d1/model.ts +1176 -0
  192. package/cloudflare/shims/sequelize-d1/operators.ts +306 -0
  193. package/cloudflare/shims/sequelize-d1/retry.ts +85 -0
  194. package/cloudflare/shims/sequelize-d1/sequelize-class.ts +119 -0
  195. package/cloudflare/shims/sequelize-d1/timing.ts +81 -0
  196. package/cloudflare/shims/sequelize-d1/types.ts +35 -0
  197. package/cloudflare/shims/stripe-cf.ts +29 -0
  198. package/cloudflare/shims/ws-lite.ts +103 -0
  199. package/cloudflare/shims/xss.ts +3 -0
  200. package/cloudflare/tests/shims/cron.spec.ts +210 -0
  201. package/cloudflare/tests/shims/queue-delayed-persist.spec.ts +87 -0
  202. package/cloudflare/tests/shims/queue-scheduled.spec.ts +186 -0
  203. package/cloudflare/vite.config.ts +162 -0
  204. package/cloudflare/worker.ts +1608 -0
  205. package/cloudflare/wrangler.json +63 -0
  206. package/cloudflare/wrangler.jsonc +75 -0
  207. package/cloudflare/wrangler.staging.json +67 -0
  208. package/cloudflare/wrangler.toml +28 -0
  209. package/jest.config.js +4 -12
  210. package/package.json +30 -22
  211. package/scripts/seed-google-play.ts +79 -0
  212. package/src/app.tsx +62 -4
  213. package/src/components/customer/link.tsx +9 -13
  214. package/src/components/customer/notification-preference.tsx +3 -2
  215. package/src/components/filter-toolbar.tsx +4 -0
  216. package/src/components/invoice/list.tsx +9 -1
  217. package/src/components/invoice-pdf/utils.ts +2 -1
  218. package/src/components/layout/admin.tsx +39 -5
  219. package/src/components/layout/user-cf.tsx +77 -0
  220. package/src/components/payment-intent/actions.tsx +23 -3
  221. package/src/components/payment-method/app-store.tsx +103 -0
  222. package/src/components/payment-method/form.tsx +7 -1
  223. package/src/components/payment-method/google-play.tsx +85 -0
  224. package/src/components/safe-did-address.tsx +75 -0
  225. package/src/components/subscription/list.tsx +20 -0
  226. package/src/libs/patch-user-card.ts +25 -0
  227. package/src/libs/util.ts +5 -7
  228. package/src/locales/en.tsx +63 -0
  229. package/src/locales/zh.tsx +63 -0
  230. package/src/pages/admin/billing/meter-events/index.tsx +4 -0
  231. package/src/pages/admin/billing/subscriptions/detail.tsx +80 -0
  232. package/src/pages/admin/customers/customers/detail.tsx +8 -2
  233. package/src/pages/admin/customers/customers/index.tsx +2 -2
  234. package/src/pages/admin/overview.tsx +3 -1
  235. package/src/pages/admin/settings/payment-methods/create.tsx +12 -0
  236. package/src/pages/admin/settings/payment-methods/index.tsx +1 -1
  237. package/src/pages/customer/subscription/detail.tsx +4 -4
  238. package/tsconfig.api.json +1 -6
  239. package/tsconfig.json +3 -4
  240. package/tsconfig.types.json +2 -1
  241. package/vite.config.ts +6 -1
@@ -1265,6 +1265,55 @@ export default flat({
1265
1265
  tip: '交易标记为确认需要的区块数',
1266
1266
  },
1267
1267
  },
1268
+ google_play: {
1269
+ package_name: {
1270
+ label: '应用包名',
1271
+ tip: '例如 com.example.app,在 Play Console 中配置',
1272
+ },
1273
+ service_account_json: {
1274
+ label: '服务账号 JSON',
1275
+ tip: '从 Google Cloud Console 下载的 service account credentials JSON,整段粘贴',
1276
+ invalidJson: '不是合法的 JSON',
1277
+ missingFields: 'JSON 缺少 client_email 或 private_key 字段',
1278
+ detectedClient: '识别到客户端',
1279
+ },
1280
+ pubsub_topic_name: {
1281
+ label: 'Pub/Sub 主题名(可选)',
1282
+ tip: 'projects/<project-id>/topics/<topic-name>,用于接收 RTDN',
1283
+ },
1284
+ },
1285
+ app_store: {
1286
+ bundle_id: {
1287
+ label: '应用 Bundle ID',
1288
+ tip: '例如 com.example.app,在 App Store Connect 中配置',
1289
+ },
1290
+ environment: {
1291
+ label: '环境',
1292
+ tip: 'StoreKit 2 JWS 中携带的 environment 必须与此匹配',
1293
+ production: '正式环境',
1294
+ sandbox: '沙盒环境',
1295
+ },
1296
+ shared_secret: {
1297
+ label: 'Shared Secret(StoreKit 1 用)',
1298
+ tip: 'App-Specific Shared Secret,用于 legacy receipt 校验。StoreKit 2 JWS 不需要。在 App Store Connect → App Information → App-Specific Shared Secret',
1299
+ },
1300
+ serverApi: {
1301
+ heading: 'Server API 凭据(可选)',
1302
+ tip: 'StoreKit 2 JWS 校验不需要凭据;只在调用 App Store Server API 查询订阅状态时使用。三项需同时填写。',
1303
+ },
1304
+ issuer_id: {
1305
+ label: 'Issuer ID',
1306
+ tip: 'App Store Connect API 的 Issuer ID',
1307
+ },
1308
+ key_id: {
1309
+ label: 'Key ID',
1310
+ tip: 'App Store Connect API 的 Key ID',
1311
+ },
1312
+ private_key_pem: {
1313
+ label: '私钥 (.p8 内容)',
1314
+ tip: '从 App Store Connect 下载的 .p8 文件内容,整段粘贴',
1315
+ },
1316
+ },
1268
1317
  },
1269
1318
  paymentCurrency: {
1270
1319
  name: '支付货币',
@@ -1452,7 +1501,19 @@ export default flat({
1452
1501
  product: '产品',
1453
1502
  attention: '将过期的订阅',
1454
1503
  collectionMethod: '计费',
1504
+ channel: '渠道',
1455
1505
  currentPeriod: '当前周期',
1506
+ iap: {
1507
+ googlePlayTitle: 'Google Play 订阅详情',
1508
+ appStoreTitle: 'App Store 订阅详情',
1509
+ purchaseToken: '购买令牌',
1510
+ orderId: '订单号',
1511
+ productId: '产品 ID',
1512
+ originalTransactionId: '原始交易 ID',
1513
+ transactionId: '本次交易 ID',
1514
+ expiryTime: '过期时间',
1515
+ environment: '环境',
1516
+ },
1456
1517
  trialingPeriod: '试用期',
1457
1518
  trialEnd: '试用期结束于 {date}',
1458
1519
  willEnd: '将于 {date} 结束',
@@ -1569,6 +1630,8 @@ export default flat({
1569
1630
  email: '电子邮件',
1570
1631
  phone: '电话',
1571
1632
  invoicePrefix: '账单前缀',
1633
+ googlePlayUuid: 'Google Play UUID',
1634
+ appStoreUuid: 'App Store UUID',
1572
1635
  balance: '余额 ({currency})',
1573
1636
  summary: {
1574
1637
  refund: '退款金额',
@@ -473,6 +473,10 @@ function CustomerFilter({
473
473
  e.stopPropagation();
474
474
  }}
475
475
  onClick={(e) => e.stopPropagation()}
476
+ // Stop MUI <Menu>'s built-in letter-key navigation from stealing keystrokes
477
+ // (it jumps to a MenuItem starting with the typed letter, which makes the
478
+ // search field appear to "swallow" inputs like 'a'/'w'). See #1357.
479
+ onKeyDown={(e) => e.stopPropagation()}
476
480
  />
477
481
  </Box>
478
482
  {customers.map((customer) => (
@@ -335,6 +335,86 @@ export default function SubscriptionDetail(props: { id: string }) {
335
335
  )}
336
336
  </InfoRowGroup>
337
337
  </Box>
338
+
339
+ {/* IAP details — Google Play / App Store */}
340
+ {(data.payment_details?.google_play || data.payment_details?.app_store) && (
341
+ <>
342
+ <Divider />
343
+ <Box className="section" sx={{ containerType: 'inline-size' }}>
344
+ <SectionHeader
345
+ title={
346
+ data.payment_details?.google_play
347
+ ? t('admin.subscription.iap.googlePlayTitle')
348
+ : t('admin.subscription.iap.appStoreTitle')
349
+ }
350
+ />
351
+ <InfoRowGroup
352
+ sx={{
353
+ '.info-row-value': { wordBreak: 'break-all' },
354
+ }}>
355
+ {(data as any).channel && (
356
+ <InfoRow label={t('admin.subscription.channel')} value={(data as any).channel} />
357
+ )}
358
+ {data.payment_details?.google_play && (
359
+ <>
360
+ <InfoRow
361
+ label={t('admin.subscription.iap.purchaseToken')}
362
+ value={data.payment_details.google_play.purchase_token}
363
+ />
364
+ <InfoRow
365
+ label={t('admin.subscription.iap.orderId')}
366
+ value={data.payment_details.google_play.order_id || '—'}
367
+ />
368
+ <InfoRow
369
+ label={t('admin.subscription.iap.productId')}
370
+ value={data.payment_details.google_play.product_id}
371
+ />
372
+ <InfoRow
373
+ label={t('admin.subscription.iap.expiryTime')}
374
+ value={
375
+ data.payment_details.google_play.expiry_time_millis
376
+ ? formatTime(Number(data.payment_details.google_play.expiry_time_millis))
377
+ : '—'
378
+ }
379
+ />
380
+ <InfoRow
381
+ label={t('admin.subscription.iap.environment')}
382
+ value={data.payment_details.google_play.environment || (data as any).environment || '—'}
383
+ />
384
+ </>
385
+ )}
386
+ {data.payment_details?.app_store && (
387
+ <>
388
+ <InfoRow
389
+ label={t('admin.subscription.iap.originalTransactionId')}
390
+ value={data.payment_details.app_store.original_transaction_id}
391
+ />
392
+ <InfoRow
393
+ label={t('admin.subscription.iap.transactionId')}
394
+ value={data.payment_details.app_store.transaction_id || '—'}
395
+ />
396
+ <InfoRow
397
+ label={t('admin.subscription.iap.productId')}
398
+ value={data.payment_details.app_store.product_id}
399
+ />
400
+ <InfoRow
401
+ label={t('admin.subscription.iap.expiryTime')}
402
+ value={
403
+ data.payment_details.app_store.expires_at
404
+ ? formatTime(data.payment_details.app_store.expires_at * 1000)
405
+ : '—'
406
+ }
407
+ />
408
+ <InfoRow
409
+ label={t('admin.subscription.iap.environment')}
410
+ value={data.payment_details.app_store.environment || (data as any).environment || '—'}
411
+ />
412
+ </>
413
+ )}
414
+ </InfoRowGroup>
415
+ </Box>
416
+ </>
417
+ )}
338
418
  <Divider />
339
419
  {/* Discount Information */}
340
420
  {(data as any).discountStats && (
@@ -1,5 +1,4 @@
1
1
  /* eslint-disable react/no-unstable-nested-components */
2
- import DidAddress from '@arcblock/ux/lib/DID';
3
2
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
4
3
  import Toast from '@arcblock/ux/lib/Toast';
5
4
  import {
@@ -19,6 +18,7 @@ import { useRequest, useSetState } from 'ahooks';
19
18
  import { defaultCountries, FlagEmoji, parseCountry } from 'react-international-phone';
20
19
 
21
20
  import { useMemo } from 'react';
21
+ import SafeDidAddress from '../../../../components/safe-did-address';
22
22
  import BalanceList from '../../../../components/balance-list';
23
23
  import Copyable from '../../../../components/copyable';
24
24
  import EditCustomer from '../../../../components/customer/edit';
@@ -343,12 +343,18 @@ export default function CustomerDetail(props: { id: string }) {
343
343
  }}>
344
344
  <InfoRow
345
345
  label={t('common.did')}
346
- value={<DidAddress did={data.customer.did} chainId={livemode ? 'main' : 'beta'} showQrcode />}
346
+ value={<SafeDidAddress did={data.customer.did} chainId={livemode ? 'main' : 'beta'} showQrcode />}
347
347
  />
348
348
  <InfoRow label={t('admin.customer.name')} value={data.customer.name} />
349
349
  <InfoRow label={t('common.createdAt')} value={formatTime(data.customer.created_at)} />
350
350
 
351
351
  <InfoRow label={t('admin.customer.invoicePrefix')} value={data.customer.invoice_prefix} />
352
+ {(data.customer as any).google_play_uuid && (
353
+ <InfoRow label={t('admin.customer.googlePlayUuid')} value={(data.customer as any).google_play_uuid} />
354
+ )}
355
+ {(data.customer as any).app_store_uuid && (
356
+ <InfoRow label={t('admin.customer.appStoreUuid')} value={(data.customer as any).app_store_uuid} />
357
+ )}
352
358
  <InfoRow label={t('common.updatedAt')} value={formatTime(data.customer.updated_at)} />
353
359
  {state.editing.customer && (
354
360
  <EditCustomer
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable react/no-unstable-nested-components */
2
2
  import { getDurableData } from '@arcblock/ux/lib/Datatable';
3
- import DidAddress from '@arcblock/ux/lib/DID';
4
3
  import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
4
  import { api, formatTime, getCustomerAvatar, Table } from '@blocklet/payment-react';
6
5
  import type { TCustomer } from '@blocklet/payment-types';
@@ -8,6 +7,7 @@ import { Avatar, CircularProgress, Stack, Typography } from '@mui/material';
8
7
  import { useLocalStorageState } from 'ahooks';
9
8
  import { useEffect, useState } from 'react';
10
9
  import { Link } from 'react-router-dom';
10
+ import SafeDidAddress from '../../../../components/safe-did-address';
11
11
 
12
12
  const fetchData = (params: Record<string, any> = {}): Promise<{ list: TCustomer[]; count: number }> => {
13
13
  const search = new URLSearchParams();
@@ -98,7 +98,7 @@ export default function CustomersList() {
98
98
  const item = data.list[index] as TCustomer;
99
99
  return (
100
100
  <Link to={`/admin/customers/${item.id}`}>
101
- <DidAddress did={item.did} />
101
+ <SafeDidAddress did={item.did} />
102
102
  </Link>
103
103
  );
104
104
  },
@@ -328,7 +328,9 @@ export default function Overview() {
328
328
  const summaryLoading = summary.loading;
329
329
  const trendLoading = trend.loading;
330
330
  const overdueLoading = overdueSummary.loading;
331
- const overdueList = overdueSummary.data?.list || [];
331
+ // Filter out items with missing currency data overdue API may return items whose
332
+ // referenced currency was deleted or failed to expand
333
+ const overdueList = (overdueSummary.data?.list || []).filter((item: any) => item?.currency?.id);
332
334
  const hasOverdue = overdueList.length > 0;
333
335
  const summaryData = summary.data;
334
336
  const summarySummary = summaryData?.summary;
@@ -52,6 +52,18 @@ export default function PaymentMethodCreate() {
52
52
  explorer_host: '',
53
53
  logo: '',
54
54
  },
55
+ google_play: {
56
+ package_name: '',
57
+ service_account_json: '',
58
+ pubsub_topic_name: '',
59
+ },
60
+ app_store: {
61
+ bundle_id: '',
62
+ environment: 'sandbox',
63
+ issuer_id: '',
64
+ key_id: '',
65
+ private_key_pem: '',
66
+ },
55
67
  },
56
68
  },
57
69
  });
@@ -453,7 +453,7 @@ export default function PaymentMethods() {
453
453
  addons={
454
454
  <>
455
455
  <Switch checked={method.active} disabled sx={{ cursor: 'default' }} />
456
- {method.type !== 'arcblock' && (
456
+ {!['arcblock', 'google_play', 'app_store'].includes(method.type) && (
457
457
  <IconButton
458
458
  onClick={(e) => {
459
459
  e.stopPropagation();
@@ -284,13 +284,13 @@ export default function CustomerSubscriptionDetail() {
284
284
 
285
285
  const renderOverdraftProtectionLabel = () => {
286
286
  const enabled = data?.overdraft_protection?.enabled;
287
+ const upcomingAmount = overdraftProtection?.upcoming?.amount || '0';
288
+ const gasAmount = overdraftProtection?.gas || '0';
287
289
  const insufficient =
288
290
  !enableOverdraftProtection ||
289
291
  overdraftProtection.unused === '0' ||
290
- new BN(overdraftProtection.unused).lt(
291
- new BN(overdraftProtection.upcoming?.amount).add(new BN(overdraftProtection.gas))
292
- );
293
- const estimateAmount = +fromUnitToToken(cycleAmount.amount, data.paymentCurrency?.decimal);
292
+ new BN(overdraftProtection.unused).lt(new BN(upcomingAmount).add(new BN(gasAmount)));
293
+ const estimateAmount = +fromUnitToToken(cycleAmount.amount || '0', data.paymentCurrency?.decimal);
294
294
 
295
295
  const remainingStake = +fromUnitToToken(overdraftProtection?.unused || '0', data.paymentCurrency?.decimal);
296
296
  const formatEstimatedDuration = (cycles: number) => {
package/tsconfig.api.json CHANGED
@@ -3,12 +3,7 @@
3
3
  "compilerOptions": {
4
4
  "outDir": "api/dist",
5
5
  "noEmit": false,
6
- "noEmitOnError": true,
7
- "typeRoots": [
8
- "./node_modules/@types",
9
- "env.d.ts",
10
- "pretty-ms-i18n.d.ts"
11
- ],
6
+ "noEmitOnError": true
12
7
  },
13
8
  "include": ["api/*.d.ts", "api/src"]
14
9
  }
package/tsconfig.json CHANGED
@@ -31,11 +31,9 @@
31
31
  "module": "commonjs" /* Specify what module code is generated. */,
32
32
  // "rootDir": "./", /* Specify the root folder within your source files. */
33
33
  // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
34
- // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
35
- // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
36
34
  // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
37
35
  // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
38
- // "types": [], /* Specify type package names to be included without being referenced in a source file. */
36
+ "types": ["node", "react", "react-dom", "express", "cookie-parser", "cors", "debug", "dotenv-flow", "jest"], /* Only include types explicitly used by this package */
39
37
  // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
40
38
  // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
41
39
  // "resolveJsonModule": true, /* Enable importing .json files. */
@@ -98,5 +96,6 @@
98
96
  /* Completeness */
99
97
  // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
100
98
  "skipLibCheck": true, /* Skip type checking all .d.ts files. */
101
- }
99
+ },
100
+ "exclude": ["node_modules", "cloudflare"]
102
101
  }
@@ -5,7 +5,8 @@
5
5
  "noEmit": false,
6
6
  "declaration": true,
7
7
  "emitDeclarationOnly": true,
8
- "noEmitOnError": true
8
+ "noEmitOnError": true,
9
+ "types": ["node"]
9
10
  },
10
11
  "include": ["api/*.d.ts", "api/src/store/models"]
11
12
  }
package/vite.config.ts CHANGED
@@ -56,6 +56,7 @@ export default defineConfig(({ mode }) => {
56
56
  createBlockletPlugin({
57
57
  disableDynamicAssetHost: false,
58
58
  chunkSizeLimit: 3500,
59
+ disableNodePolyfills: true,
59
60
  }),
60
61
  svgr(),
61
62
  process.env.ANALYZE && visualizer({ open: true, gzipSize: true, brotliSize: true }),
@@ -106,6 +107,10 @@ export default defineConfig(({ mode }) => {
106
107
  },
107
108
  },
108
109
  },
110
+ define: {
111
+ global: 'globalThis',
112
+ 'process.env': {},
113
+ },
109
114
  optimizeDeps: {
110
115
  include: ['react', 'react-dom', 'react/jsx-runtime'],
111
116
  esbuildOptions: { mainFields: ['module', 'main'], resolveExtensions: ['.ts', '.tsx', '.js', '.jsx'] },
@@ -128,4 +133,4 @@ export default defineConfig(({ mode }) => {
128
133
  ],
129
134
  },
130
135
  };
131
- });
136
+ });