airwallexInit.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import { init,InitResult,createElement, type Payment } from '@airwallex/components-sdk';
  2. // export {Payment};
  3. export type AirwallexCartNumberElementType = Payment.CardNumberElementType;
  4. export type AirwallexCvcElementType = Payment.CvcElementType;
  5. export type AirwallexExpiryDateElementType = Payment.ExpiryDateElementType;
  6. export interface AirwallexCardElements{
  7. cardNumber?: AirwallexCartNumberElementType;
  8. cvc?: AirwallexCvcElementType;
  9. expiry?: AirwallexExpiryDateElementType;
  10. }
  11. type ElementType =
  12. | AirwallexCartNumberElementType
  13. | AirwallexCvcElementType
  14. | AirwallexExpiryDateElementType;
  15. let initPromise: Promise<InitResult> | null = null;
  16. export function airwallexInit() {
  17. if (!initPromise) {
  18. initPromise = init({
  19. env:
  20. process.env.NEXT_PUBLIC_APP_ENV !== 'production'
  21. ? 'demo'
  22. : 'prod',
  23. enabledElements: ['payments'],
  24. });
  25. }
  26. return initPromise;
  27. }
  28. class AirwallexManager {
  29. private elements: AirwallexCardElements = {};
  30. private createPromise: Promise<AirwallexCardElements> | null = null;
  31. private listeners = new Map<ElementType, Map<Payment.SplitElementEventCode, boolean>>();
  32. // private created = false;
  33. // async init() {
  34. // if (this.created) return;
  35. // this.created = true;
  36. // }
  37. async createElements() {
  38. if (this.elements.cardNumber) {
  39. return this.elements;
  40. }
  41. if (this.createPromise) {
  42. return this.createPromise;
  43. }
  44. this.createPromise = Promise.all([
  45. createElement("cardNumber"),
  46. createElement("cvc"),
  47. createElement("expiry")
  48. ]).then(([cardNumber,cvc,expiry]) => {
  49. this.elements = {
  50. cardNumber,
  51. cvc,
  52. expiry
  53. };
  54. return this.elements;
  55. });
  56. return this.createPromise;
  57. }
  58. mount(containerIds: {
  59. cardNumber: string;
  60. cvc: string;
  61. expiry: string;
  62. }) {
  63. this.elements.cardNumber?.mount(containerIds.cardNumber);
  64. this.elements.cvc?.mount(containerIds.cvc);
  65. this.elements.expiry?.mount(containerIds.expiry);
  66. }
  67. unmount() {
  68. this.elements.cardNumber?.unmount();
  69. this.elements.cvc?.unmount();
  70. this.elements.expiry?.unmount();
  71. }
  72. on<EventCode extends Payment.SplitElementEventCode>(el: ElementType, event: EventCode, handler: Payment.SplitElementEventHandler<EventCode>) {
  73. let eventMap = this.listeners.get(el);
  74. if (!eventMap) {
  75. eventMap = new Map<Payment.SplitElementEventCode, boolean>([[event, false]]);
  76. this.listeners.set(el, eventMap);
  77. }
  78. if(eventMap.get(event)) return; // 注册过就返回
  79. el.on(event, handler);
  80. eventMap.set(event,true);
  81. }
  82. destroy() {
  83. const { cardNumber, cvc, expiry } = this.elements;
  84. [cardNumber, cvc, expiry].forEach((el) => {
  85. if (!el) return;
  86. el.unmount();
  87. el.destroy();
  88. });
  89. this.elements = {};
  90. }
  91. getElements() {
  92. return this.elements;
  93. }
  94. }
  95. export const airwallexManager = new AirwallexManager();