@cimplify/sdk 0.8.4 → 0.8.6

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/react.mjs CHANGED
@@ -1557,6 +1557,10 @@ var DEFAULT_POLL_INTERVAL_MS = 3e3;
1557
1557
  var DEFAULT_MAX_POLL_ATTEMPTS = 60;
1558
1558
  var MAX_CONSECUTIVE_NETWORK_ERRORS = 5;
1559
1559
  var CARD_PROVIDER_PAYSTACK = "paystack";
1560
+ var NEXT_ACTION_NONE = "none";
1561
+ var NEXT_ACTION_CARD_POPUP = "card_popup";
1562
+ var NEXT_ACTION_REDIRECT = "redirect";
1563
+ var NEXT_ACTION_AUTHORIZATION = "authorization";
1560
1564
  function normalizeCardPopupError(error) {
1561
1565
  if (!error || error === "PAYMENT_CANCELLED" || error === "CANCELLED") {
1562
1566
  return "PAYMENT_CANCELLED";
@@ -1596,7 +1600,8 @@ function isValidMobileMoneyProvider(value) {
1596
1600
  return VALID_MOBILE_MONEY_PROVIDERS.has(value);
1597
1601
  }
1598
1602
  function normalizeAuthorizationType(value) {
1599
- return value === "otp" || value === "pin" ? value : void 0;
1603
+ const lower = value?.toLowerCase();
1604
+ return lower === "otp" || lower === "pin" ? lower : void 0;
1600
1605
  }
1601
1606
  function formatMoney2(value) {
1602
1607
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -1643,6 +1648,9 @@ var CheckoutResolver = class {
1643
1648
  if (!checkoutResult.order_id) {
1644
1649
  return this.fail("CHECKOUT_FAILED", "Checkout did not return an order ID.", false);
1645
1650
  }
1651
+ if (checkoutResult.next_action) {
1652
+ return this.resolveNextAction(checkoutResult);
1653
+ }
1646
1654
  let latestCheckoutResult = checkoutResult;
1647
1655
  let authorizationType = normalizeAuthorizationType(checkoutResult.authorization_type);
1648
1656
  let paymentReference = checkoutResult.payment_reference;
@@ -1758,6 +1766,110 @@ var CheckoutResolver = class {
1758
1766
  return this.fail("CHECKOUT_FAILED", message, true);
1759
1767
  }
1760
1768
  }
1769
+ async resolveNextAction(checkoutResult) {
1770
+ const action = checkoutResult.next_action;
1771
+ if (this.isSuccessfulStatus(checkoutResult.payment_status)) {
1772
+ return this.finalizeSuccess(checkoutResult);
1773
+ }
1774
+ let latestCheckoutResult = checkoutResult;
1775
+ let paymentReference = checkoutResult.payment_reference;
1776
+ switch (action.type) {
1777
+ case NEXT_ACTION_NONE:
1778
+ return this.finalizeSuccess(checkoutResult);
1779
+ case NEXT_ACTION_CARD_POPUP: {
1780
+ const provider = normalizeCardProvider(action.provider);
1781
+ this.emit("awaiting_authorization", {
1782
+ display_text: "Complete payment in the card authorization popup.",
1783
+ order_id: checkoutResult.order_id,
1784
+ order_number: checkoutResult.order_number
1785
+ });
1786
+ if (!this.allowPopups) {
1787
+ return this.fail(
1788
+ "PROVIDER_UNAVAILABLE",
1789
+ "Card payment popup is unavailable in this environment.",
1790
+ false
1791
+ );
1792
+ }
1793
+ const popupResult = await openCardPopup(
1794
+ provider,
1795
+ checkoutResult,
1796
+ this.checkoutData.customer.email || "customer@cimplify.io",
1797
+ this.getOrderCurrency(checkoutResult),
1798
+ this.signal
1799
+ );
1800
+ if (!popupResult.success) {
1801
+ const popupError = normalizeCardPopupError(popupResult.error);
1802
+ if (popupError === "POPUP_BLOCKED") {
1803
+ return this.fail(
1804
+ "POPUP_BLOCKED",
1805
+ "Unable to open card payment popup. Please allow popups and try again.",
1806
+ true
1807
+ );
1808
+ }
1809
+ if (popupError === "PROVIDER_UNAVAILABLE") {
1810
+ return this.fail("PROVIDER_UNAVAILABLE", "Card payment provider is unavailable.", false);
1811
+ }
1812
+ return this.fail("PAYMENT_CANCELLED", "Card payment was cancelled before completion.", true);
1813
+ }
1814
+ paymentReference = popupResult.reference || paymentReference;
1815
+ break;
1816
+ }
1817
+ case NEXT_ACTION_REDIRECT: {
1818
+ if (typeof window !== "undefined" && this.returnUrl) {
1819
+ window.location.assign(action.authorization_url);
1820
+ return this.fail("REDIRECT_REQUIRED", "Redirecting to complete payment authorization.", true);
1821
+ }
1822
+ if (typeof window !== "undefined") {
1823
+ const popup = window.open(
1824
+ action.authorization_url,
1825
+ "cimplify-auth",
1826
+ "width=520,height=760,noopener,noreferrer"
1827
+ );
1828
+ if (!popup) {
1829
+ return this.fail(
1830
+ "POPUP_BLOCKED",
1831
+ "Authorization popup was blocked. Please allow popups and retry.",
1832
+ true
1833
+ );
1834
+ }
1835
+ }
1836
+ break;
1837
+ }
1838
+ case NEXT_ACTION_AUTHORIZATION: {
1839
+ const authType = normalizeAuthorizationType(action.authorization_type);
1840
+ const authorization = await this.handleAuthorization({
1841
+ authorizationType: authType,
1842
+ paymentReference,
1843
+ displayText: action.display_text,
1844
+ provider: checkoutResult.provider
1845
+ });
1846
+ if (!authorization.ok) {
1847
+ return authorization.result;
1848
+ }
1849
+ if (authorization.value) {
1850
+ latestCheckoutResult = authorization.value;
1851
+ paymentReference = authorization.value.payment_reference || paymentReference;
1852
+ if (this.isSuccessfulStatus(authorization.value.payment_status)) {
1853
+ return this.finalizeSuccess(authorization.value);
1854
+ }
1855
+ if (this.isFailureStatus(authorization.value.payment_status)) {
1856
+ return this.fail(
1857
+ "AUTHORIZATION_FAILED",
1858
+ authorization.value.display_text || "Payment authorization failed.",
1859
+ false
1860
+ );
1861
+ }
1862
+ }
1863
+ break;
1864
+ }
1865
+ }
1866
+ return this.pollUntilTerminal({
1867
+ orderId: checkoutResult.order_id,
1868
+ latestCheckoutResult,
1869
+ paymentReference,
1870
+ authorizationType: normalizeAuthorizationType(checkoutResult.authorization_type)
1871
+ });
1872
+ }
1761
1873
  async pollUntilTerminal(input) {
1762
1874
  let consecutiveErrors = 0;
1763
1875
  let latestCheckoutResult = input.latestCheckoutResult;
@@ -3340,6 +3452,7 @@ var CimplifyElement = class {
3340
3452
  this.iframe = null;
3341
3453
  this.container = null;
3342
3454
  this.mounted = false;
3455
+ this.pendingInit = null;
3343
3456
  this.eventHandlers = /* @__PURE__ */ new Map();
3344
3457
  this.resolvers = /* @__PURE__ */ new Map();
3345
3458
  this.listening = false;
@@ -3465,23 +3578,9 @@ var CimplifyElement = class {
3465
3578
  );
3466
3579
  this.iframe = iframe;
3467
3580
  this.container.appendChild(iframe);
3468
- iframe.onload = () => {
3469
- const publicKey = this.parent.getPublicKey();
3470
- this.sendMessage({
3471
- type: MESSAGE_TYPES.INIT,
3472
- businessId: resolvedBusinessId,
3473
- publicKey,
3474
- demoMode: publicKey.length === 0,
3475
- prefillEmail: this.options.prefillEmail,
3476
- appearance: this.parent.getAppearance(),
3477
- orderTypes: this.options.orderTypes,
3478
- defaultOrderType: this.options.defaultOrderType,
3479
- renderSubmitButton: true
3480
- });
3481
- const token = this.parent.getAccessToken();
3482
- if (token && this.type !== ELEMENT_TYPES.AUTH) {
3483
- this.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
3484
- }
3581
+ this.pendingInit = {
3582
+ businessId: resolvedBusinessId,
3583
+ publicKey: this.parent.getPublicKey()
3485
3584
  };
3486
3585
  }
3487
3586
  handleMessage(event) {
@@ -3502,6 +3601,25 @@ var CimplifyElement = class {
3502
3601
  switch (message.type) {
3503
3602
  case MESSAGE_TYPES.READY:
3504
3603
  if (this.iframe && message.height) this.iframe.style.height = `${message.height}px`;
3604
+ if (this.pendingInit) {
3605
+ const { publicKey } = this.pendingInit;
3606
+ this.sendMessage({
3607
+ type: MESSAGE_TYPES.INIT,
3608
+ businessId: this.pendingInit.businessId,
3609
+ publicKey,
3610
+ demoMode: publicKey.length === 0,
3611
+ prefillEmail: this.options.prefillEmail,
3612
+ appearance: this.parent.getAppearance(),
3613
+ orderTypes: this.options.orderTypes,
3614
+ defaultOrderType: this.options.defaultOrderType,
3615
+ renderSubmitButton: true
3616
+ });
3617
+ const token = this.parent.getAccessToken();
3618
+ if (token && this.type !== ELEMENT_TYPES.AUTH) {
3619
+ this.sendMessage({ type: MESSAGE_TYPES.SET_TOKEN, token });
3620
+ }
3621
+ this.pendingInit = null;
3622
+ }
3505
3623
  this.emit(EVENT_TYPES.READY, { height: message.height });
3506
3624
  break;
3507
3625
  case MESSAGE_TYPES.HEIGHT_CHANGE:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cimplify/sdk",
3
- "version": "0.8.4",
3
+ "version": "0.8.6",
4
4
  "description": "Cimplify Commerce SDK for storefronts",
5
5
  "keywords": [
6
6
  "cimplify",