@doujins/payments-ui 0.1.3 → 0.1.5

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,10 @@ 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(/^\/+|\/+$/g, "");
124
+ const baseUrl = config.baseUrl.replace(/^\/+|\/+$/g, "");
125
+ const url = new URL(`${baseUrl}${path.endsWith("v1") ? "/" : "/v1/"}${path}`);
131
126
  if (query) {
132
127
  Object.entries(query).forEach(([key, value]) => {
133
128
  if (value === void 0 || value === null) return;
@@ -137,8 +132,7 @@ var createClient = (config) => {
137
132
  return url.toString();
138
133
  };
139
134
  const request = async (method, path, options) => {
140
- const target = options?.target ?? "billing";
141
- const url = buildUrl(path, options?.query, target);
135
+ const url = buildUrl(path, options?.query);
142
136
  const headers = {
143
137
  "Content-Type": "application/json",
144
138
  ...defaultHeaders,
@@ -184,52 +178,49 @@ var createClient = (config) => {
184
178
  async listPaymentMethods(params) {
185
179
  const result = await request(
186
180
  "GET",
187
- "/v1/me/payment-methods",
181
+ "/me/payment-methods",
188
182
  {
189
183
  query: {
190
184
  limit: params?.limit,
191
185
  offset: params?.offset,
192
186
  include_inactive: params?.includeInactive
193
- },
194
- target: "account"
187
+ }
195
188
  }
196
189
  );
197
190
  return normalizeList(result);
198
191
  },
199
192
  createPaymentMethod(payload) {
200
- return request("POST", "/v1/me/payment-methods", {
201
- body: payload,
202
- target: "account"
193
+ return request("POST", "/me/payment-methods", {
194
+ body: payload
203
195
  });
204
196
  },
205
197
  updatePaymentMethod(id, payload) {
206
198
  return request("PUT", `/me/payment-methods/${id}`, {
207
- body: payload,
208
- target: "account"
199
+ body: payload
209
200
  });
210
201
  },
211
202
  deletePaymentMethod(id) {
212
- return request("DELETE", `/me/payment-methods/${id}`, {
213
- target: "account"
214
- });
203
+ return request("DELETE", `/me/payment-methods/${id}`, {});
215
204
  },
216
205
  activatePaymentMethod(id) {
217
- return request("PUT", `/me/payment-methods/${id}/activate`, {
218
- target: "account"
219
- });
206
+ return request("PUT", `/me/payment-methods/${id}/activate`, {});
220
207
  },
221
- checkout(payload) {
222
- return request("POST", "/v1/me/checkout", {
223
- body: payload
208
+ checkout(payload, idempotencyKey) {
209
+ const key = idempotencyKey ?? crypto.randomUUID();
210
+ return request("POST", "/me/checkout", {
211
+ body: payload,
212
+ headers: {
213
+ "Idempotency-Key": key
214
+ }
224
215
  });
225
216
  },
226
217
  cancelSubscription(feedback) {
227
- return request("POST", "/v1/me/subscriptions/cancel", {
218
+ return request("POST", "/me/subscriptions/cancel", {
228
219
  body: feedback ? { feedback } : void 0
229
220
  });
230
221
  },
231
222
  async getPaymentHistory(params) {
232
- const result = await request("GET", "/v1/me/payments", {
223
+ const result = await request("GET", "/me/payments", {
233
224
  query: {
234
225
  limit: params?.limit,
235
226
  offset: params?.offset,
@@ -241,7 +232,7 @@ var createClient = (config) => {
241
232
  async getSolanaTokens() {
242
233
  const response = await request(
243
234
  "GET",
244
- "/v1/solana/tokens"
235
+ "/solana/tokens"
245
236
  );
246
237
  if (Array.isArray(response)) {
247
238
  return response;
@@ -249,7 +240,7 @@ var createClient = (config) => {
249
240
  return response.tokens ?? [];
250
241
  },
251
242
  async createSolanaPayIntent(payload) {
252
- const response = await request("POST", "/v1/solana/pay", {
243
+ const response = await request("POST", "/solana/pay", {
253
244
  body: {
254
245
  price_id: payload.priceId,
255
246
  token: payload.token,
@@ -2079,7 +2070,8 @@ var useSubscriptionActions = () => {
2079
2070
  processor = "nmi",
2080
2071
  provider,
2081
2072
  paymentToken,
2082
- billing
2073
+ billing,
2074
+ idempotencyKey
2083
2075
  }) => {
2084
2076
  const payload = {
2085
2077
  price_id: ensurePrice(priceId),
@@ -2095,7 +2087,7 @@ var useSubscriptionActions = () => {
2095
2087
  zip: billing.postalCode,
2096
2088
  country: billing.country
2097
2089
  };
2098
- return client.checkout(payload);
2090
+ return client.checkout(payload, idempotencyKey);
2099
2091
  },
2100
2092
  [client]
2101
2093
  );
@@ -2105,7 +2097,8 @@ var useSubscriptionActions = () => {
2105
2097
  processor = "nmi",
2106
2098
  provider,
2107
2099
  paymentMethodId,
2108
- email
2100
+ email,
2101
+ idempotencyKey
2109
2102
  }) => {
2110
2103
  const payload = {
2111
2104
  price_id: ensurePrice(priceId),
@@ -2114,7 +2107,7 @@ var useSubscriptionActions = () => {
2114
2107
  payment_method_id: paymentMethodId,
2115
2108
  email
2116
2109
  };
2117
- return client.checkout(payload);
2110
+ return client.checkout(payload, idempotencyKey);
2118
2111
  },
2119
2112
  [client]
2120
2113
  );
@@ -2126,7 +2119,8 @@ var useSubscriptionActions = () => {
2126
2119
  lastName,
2127
2120
  zipCode,
2128
2121
  country,
2129
- processor = "ccbill"
2122
+ processor = "ccbill",
2123
+ idempotencyKey
2130
2124
  }) => {
2131
2125
  const payload = {
2132
2126
  price_id: ensurePrice(priceId),
@@ -2137,7 +2131,7 @@ var useSubscriptionActions = () => {
2137
2131
  zip: zipCode,
2138
2132
  country
2139
2133
  };
2140
- return client.checkout(payload);
2134
+ return client.checkout(payload, idempotencyKey);
2141
2135
  },
2142
2136
  [client]
2143
2137
  );
@@ -2164,7 +2158,13 @@ var SubscriptionCheckoutModal = ({
2164
2158
  initialMode = "cards"
2165
2159
  }) => {
2166
2160
  const [showSuccess, setShowSuccess] = React17.useState(false);
2161
+ const [idempotencyKey, setIdempotencyKey] = React17.useState(() => crypto.randomUUID());
2167
2162
  const { subscribeWithCard, subscribeWithSavedMethod } = useSubscriptionActions();
2163
+ React17.useEffect(() => {
2164
+ if (open) {
2165
+ setIdempotencyKey(crypto.randomUUID());
2166
+ }
2167
+ }, [open, priceId]);
2168
2168
  const handleClose = React17.useCallback(
2169
2169
  (nextOpen) => {
2170
2170
  onOpenChange(nextOpen);
@@ -2196,7 +2196,8 @@ var SubscriptionCheckoutModal = ({
2196
2196
  priceId: ensurePrice(),
2197
2197
  provider,
2198
2198
  paymentToken: token,
2199
- billing
2199
+ billing,
2200
+ idempotencyKey
2200
2201
  });
2201
2202
  assertCheckoutSuccess(response.status, response.message);
2202
2203
  notifySuccess();
@@ -2206,7 +2207,8 @@ var SubscriptionCheckoutModal = ({
2206
2207
  priceId: ensurePrice(),
2207
2208
  provider,
2208
2209
  paymentMethodId,
2209
- email: userEmail ?? ""
2210
+ email: userEmail ?? "",
2211
+ idempotencyKey
2210
2212
  });
2211
2213
  assertCheckoutSuccess(response.status, response.message);
2212
2214
  notifySuccess();
@@ -2436,11 +2438,10 @@ var PaymentProvider = ({
2436
2438
  return config.fetcher(normalizedInput, init);
2437
2439
  }) : void 0;
2438
2440
  return createClient({
2439
- billingBaseUrl: config.endpoints.billingBaseUrl,
2440
- accountBaseUrl: config.endpoints.accountBaseUrl,
2441
+ fetch: wrappedFetch,
2442
+ baseUrl: config.baseUrl,
2441
2443
  getAuthToken: authProvider,
2442
- defaultHeaders: config.defaultHeaders,
2443
- fetch: wrappedFetch
2444
+ defaultHeaders: config.defaultHeaders
2444
2445
  });
2445
2446
  }, [config]);
2446
2447
  const solanaEndpoint = React17.useMemo(() => {