@doujins/payments-ui 0.1.2 → 0.1.4

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/index.cjs CHANGED
@@ -99,7 +99,7 @@ var ClientApiError = class extends Error {
99
99
  this.request = request;
100
100
  }
101
101
  };
102
- var ensureFetch = (fetchImpl) => {
102
+ var getFetchFn = (fetchImpl) => {
103
103
  if (fetchImpl) return fetchImpl;
104
104
  if (typeof globalThis.fetch === "function") {
105
105
  return globalThis.fetch.bind(globalThis);
@@ -107,12 +107,7 @@ var ensureFetch = (fetchImpl) => {
107
107
  throw new Error("payments-ui: global fetch is not available");
108
108
  };
109
109
  var createClient = (config) => {
110
- const fetchImpl = ensureFetch(config.fetch);
111
- const normalizeBase = (value) => value.replace(/\/$/, "");
112
- const billingBaseUrl = normalizeBase(config.billingBaseUrl);
113
- const accountBaseUrl = normalizeBase(
114
- config.accountBaseUrl ?? config.billingBaseUrl
115
- );
110
+ const fetchImpl = getFetchFn(config.fetch);
116
111
  const defaultHeaders = config.defaultHeaders ?? {};
117
112
  const resolveAuthToken = async () => {
118
113
  if (!config.getAuthToken) return null;
@@ -124,10 +119,9 @@ var createClient = (config) => {
124
119
  return null;
125
120
  }
126
121
  };
127
- const buildUrl = (path, query, target) => {
128
- const normalizedPath = path.startsWith("/") ? path : `/${path}`;
129
- const baseUrl = target === "account" ? accountBaseUrl : billingBaseUrl;
130
- const url = new URL(`${baseUrl}${normalizedPath}`);
122
+ const buildUrl = (path, query) => {
123
+ path = path.replace(/^\/+/, "");
124
+ const url = new URL(`${config.baseUrl.replace(/^\/+/, "")}${path.endsWith("v1") ? "" : "/v1"}${path}`);
131
125
  if (query) {
132
126
  Object.entries(query).forEach(([key, value]) => {
133
127
  if (value === void 0 || value === null) return;
@@ -137,8 +131,7 @@ var createClient = (config) => {
137
131
  return url.toString();
138
132
  };
139
133
  const request = async (method, path, options) => {
140
- const target = options?.target ?? "billing";
141
- const url = buildUrl(path, options?.query, target);
134
+ const url = buildUrl(path, options?.query);
142
135
  const headers = {
143
136
  "Content-Type": "application/json",
144
137
  ...defaultHeaders,
@@ -190,37 +183,34 @@ var createClient = (config) => {
190
183
  limit: params?.limit,
191
184
  offset: params?.offset,
192
185
  include_inactive: params?.includeInactive
193
- },
194
- target: "account"
186
+ }
195
187
  }
196
188
  );
197
189
  return normalizeList(result);
198
190
  },
199
191
  createPaymentMethod(payload) {
200
192
  return request("POST", "/me/payment-methods", {
201
- body: payload,
202
- target: "account"
193
+ body: payload
203
194
  });
204
195
  },
205
196
  updatePaymentMethod(id, payload) {
206
197
  return request("PUT", `/me/payment-methods/${id}`, {
207
- body: payload,
208
- target: "account"
198
+ body: payload
209
199
  });
210
200
  },
211
201
  deletePaymentMethod(id) {
212
- return request("DELETE", `/me/payment-methods/${id}`, {
213
- target: "account"
214
- });
202
+ return request("DELETE", `/me/payment-methods/${id}`, {});
215
203
  },
216
204
  activatePaymentMethod(id) {
217
- return request("PUT", `/me/payment-methods/${id}/activate`, {
218
- target: "account"
219
- });
205
+ return request("PUT", `/me/payment-methods/${id}/activate`, {});
220
206
  },
221
- checkout(payload) {
207
+ checkout(payload, idempotencyKey) {
208
+ const key = idempotencyKey ?? crypto.randomUUID();
222
209
  return request("POST", "/me/checkout", {
223
- body: payload
210
+ body: payload,
211
+ headers: {
212
+ "Idempotency-Key": key
213
+ }
224
214
  });
225
215
  },
226
216
  cancelSubscription(feedback) {
@@ -2079,7 +2069,8 @@ var useSubscriptionActions = () => {
2079
2069
  processor = "nmi",
2080
2070
  provider,
2081
2071
  paymentToken,
2082
- billing
2072
+ billing,
2073
+ idempotencyKey
2083
2074
  }) => {
2084
2075
  const payload = {
2085
2076
  price_id: ensurePrice(priceId),
@@ -2095,7 +2086,7 @@ var useSubscriptionActions = () => {
2095
2086
  zip: billing.postalCode,
2096
2087
  country: billing.country
2097
2088
  };
2098
- return client.checkout(payload);
2089
+ return client.checkout(payload, idempotencyKey);
2099
2090
  },
2100
2091
  [client]
2101
2092
  );
@@ -2105,7 +2096,8 @@ var useSubscriptionActions = () => {
2105
2096
  processor = "nmi",
2106
2097
  provider,
2107
2098
  paymentMethodId,
2108
- email
2099
+ email,
2100
+ idempotencyKey
2109
2101
  }) => {
2110
2102
  const payload = {
2111
2103
  price_id: ensurePrice(priceId),
@@ -2114,7 +2106,7 @@ var useSubscriptionActions = () => {
2114
2106
  payment_method_id: paymentMethodId,
2115
2107
  email
2116
2108
  };
2117
- return client.checkout(payload);
2109
+ return client.checkout(payload, idempotencyKey);
2118
2110
  },
2119
2111
  [client]
2120
2112
  );
@@ -2126,7 +2118,8 @@ var useSubscriptionActions = () => {
2126
2118
  lastName,
2127
2119
  zipCode,
2128
2120
  country,
2129
- processor = "ccbill"
2121
+ processor = "ccbill",
2122
+ idempotencyKey
2130
2123
  }) => {
2131
2124
  const payload = {
2132
2125
  price_id: ensurePrice(priceId),
@@ -2137,7 +2130,7 @@ var useSubscriptionActions = () => {
2137
2130
  zip: zipCode,
2138
2131
  country
2139
2132
  };
2140
- return client.checkout(payload);
2133
+ return client.checkout(payload, idempotencyKey);
2141
2134
  },
2142
2135
  [client]
2143
2136
  );
@@ -2164,7 +2157,13 @@ var SubscriptionCheckoutModal = ({
2164
2157
  initialMode = "cards"
2165
2158
  }) => {
2166
2159
  const [showSuccess, setShowSuccess] = React17.useState(false);
2160
+ const [idempotencyKey, setIdempotencyKey] = React17.useState(() => crypto.randomUUID());
2167
2161
  const { subscribeWithCard, subscribeWithSavedMethod } = useSubscriptionActions();
2162
+ React17.useEffect(() => {
2163
+ if (open) {
2164
+ setIdempotencyKey(crypto.randomUUID());
2165
+ }
2166
+ }, [open, priceId]);
2168
2167
  const handleClose = React17.useCallback(
2169
2168
  (nextOpen) => {
2170
2169
  onOpenChange(nextOpen);
@@ -2196,7 +2195,8 @@ var SubscriptionCheckoutModal = ({
2196
2195
  priceId: ensurePrice(),
2197
2196
  provider,
2198
2197
  paymentToken: token,
2199
- billing
2198
+ billing,
2199
+ idempotencyKey
2200
2200
  });
2201
2201
  assertCheckoutSuccess(response.status, response.message);
2202
2202
  notifySuccess();
@@ -2206,7 +2206,8 @@ var SubscriptionCheckoutModal = ({
2206
2206
  priceId: ensurePrice(),
2207
2207
  provider,
2208
2208
  paymentMethodId,
2209
- email: userEmail ?? ""
2209
+ email: userEmail ?? "",
2210
+ idempotencyKey
2210
2211
  });
2211
2212
  assertCheckoutSuccess(response.status, response.message);
2212
2213
  notifySuccess();
@@ -2436,11 +2437,10 @@ var PaymentProvider = ({
2436
2437
  return config.fetcher(normalizedInput, init);
2437
2438
  }) : void 0;
2438
2439
  return createClient({
2439
- billingBaseUrl: config.endpoints.billingBaseUrl,
2440
- accountBaseUrl: config.endpoints.accountBaseUrl,
2440
+ fetch: wrappedFetch,
2441
+ baseUrl: config.baseUrl,
2441
2442
  getAuthToken: authProvider,
2442
- defaultHeaders: config.defaultHeaders,
2443
- fetch: wrappedFetch
2443
+ defaultHeaders: config.defaultHeaders
2444
2444
  });
2445
2445
  }, [config]);
2446
2446
  const solanaEndpoint = React17.useMemo(() => {