airwallexInit.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. }).catch((err) => {
  25. initPromise = null;
  26. throw err;
  27. });
  28. }
  29. return initPromise;
  30. }
  31. class AirwallexManager {
  32. private elements: AirwallexCardElements = {};
  33. private createPromise: Promise<AirwallexCardElements> | null = null;
  34. private listeners = new Map<ElementType, Map<Payment.SplitElementEventCode, boolean>>();
  35. // private created = false;
  36. // async init() {
  37. // if (this.created) return;
  38. // this.created = true;
  39. // }
  40. async createElements() {
  41. if (this.elements.cardNumber) {
  42. return this.elements;
  43. }
  44. if (this.createPromise) {
  45. return this.createPromise;
  46. }
  47. this.createPromise = Promise.all([
  48. createElement("cardNumber"),
  49. createElement("cvc"),
  50. createElement("expiry")
  51. ]).then(([cardNumber,cvc,expiry]) => {
  52. this.elements = {
  53. cardNumber,
  54. cvc,
  55. expiry
  56. };
  57. return this.elements;
  58. });
  59. return this.createPromise;
  60. }
  61. mount(containerIds: {
  62. cardNumber: string;
  63. cvc: string;
  64. expiry: string;
  65. }) {
  66. this.elements.cardNumber?.mount(containerIds.cardNumber);
  67. this.elements.cvc?.mount(containerIds.cvc);
  68. this.elements.expiry?.mount(containerIds.expiry);
  69. }
  70. unmount() {
  71. this.elements.cardNumber?.unmount();
  72. this.elements.cvc?.unmount();
  73. this.elements.expiry?.unmount();
  74. }
  75. on<EventCode extends Payment.SplitElementEventCode>(el: ElementType, event: EventCode, handler: Payment.SplitElementEventHandler<EventCode>) {
  76. let eventMap = this.listeners.get(el);
  77. if (!eventMap) {
  78. eventMap = new Map<Payment.SplitElementEventCode, boolean>([[event, false]]);
  79. this.listeners.set(el, eventMap);
  80. }
  81. if(eventMap.get(event)) return; // 注册过就返回
  82. el.on(event, handler);
  83. eventMap.set(event,true);
  84. }
  85. destroy() {
  86. const { cardNumber, cvc, expiry } = this.elements;
  87. [cardNumber, cvc, expiry].forEach((el) => {
  88. if (!el) return;
  89. el.unmount();
  90. el.destroy();
  91. });
  92. this.elements = {};
  93. }
  94. getElements() {
  95. return this.elements;
  96. }
  97. }
  98. export const airwallexManager = new AirwallexManager();