summaryrefslogtreecommitdiff
path: root/packages/taler-util/src
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-03-19 15:39:06 -0300
committerSebastian <sebasjm@gmail.com>2024-03-19 15:39:06 -0300
commit7c7086e11f641100e0dd06364a97503df348e2b2 (patch)
tree2f8ad2705fcf242e315e728642af3005b24e30b5 /packages/taler-util/src
parent3c03ac5de448880b428b61e8c4fba1d393caf054 (diff)
downloadwallet-core-7c7086e11f641100e0dd06364a97503df348e2b2.tar.gz
wallet-core-7c7086e11f641100e0dd06364a97503df348e2b2.tar.bz2
wallet-core-7c7086e11f641100e0dd06364a97503df348e2b2.zip
wip
Diffstat (limited to 'packages/taler-util/src')
-rw-r--r--packages/taler-util/src/http-client/merchant.ts499
-rw-r--r--packages/taler-util/src/http-client/types.ts281
-rw-r--r--packages/taler-util/src/http-client/utils.ts15
3 files changed, 646 insertions, 149 deletions
diff --git a/packages/taler-util/src/http-client/merchant.ts b/packages/taler-util/src/http-client/merchant.ts
index 00efc5a71..b054a04eb 100644
--- a/packages/taler-util/src/http-client/merchant.ts
+++ b/packages/taler-util/src/http-client/merchant.ts
@@ -17,20 +17,33 @@
import {
HttpStatusCode,
LibtoolVersion,
+ PaginationParams,
TalerMerchantApi,
+ codecForAbortResponse,
+ codecForAccountAddDetails,
+ codecForAccountAddResponse,
+ codecForAccountKycRedirects,
+ codecForAccountsSummaryResponse,
+ codecForBankAccountEntry,
codecForClaimResponse,
+ codecForInventorySummaryResponse,
codecForMerchantConfig,
- opKnownHttpFailure
+ codecForPaidRefundStatusResponse,
+ codecForPaymentResponse,
+ codecForQueryInstancesResponse,
+ codecForStatusGoto,
+ codecForStatusPaid,
+ codecForStatusStatusUnpaid,
+ codecForWalletRefundResponse,
+ opEmptySuccess,
+ opKnownHttpFailure,
} from "@gnu-taler/taler-util";
import {
HttpRequestLibrary,
createPlatformHttpLib,
} from "@gnu-taler/taler-util/http";
-import {
- opSuccessFromHttp,
- opUnknownFailure
-} from "../operation.js";
-import { CacheEvictor, nullEvictor } from "./utils.js";
+import { opSuccessFromHttp, opUnknownFailure } from "../operation.js";
+import { CacheEvictor, addMerchantPaginationParams, addPaginationParams, nullEvictor } from "./utils.js";
export enum TalerMerchantCacheEviction {
CREATE_ORDER,
@@ -44,7 +57,8 @@ export enum TalerMerchantCacheEviction {
*
* Uses libtool's current:revision:age versioning.
*/
-class TalerMerchantInstanceHttpClient {
+export class TalerMerchantInstanceHttpClient {
+ public readonly PROTOCOL_VERSION = "10:0:6";
readonly httpLib: HttpRequestLibrary;
readonly cacheEvictor: CacheEvictor<TalerMerchantCacheEviction>;
@@ -58,6 +72,28 @@ class TalerMerchantInstanceHttpClient {
this.cacheEvictor = cacheEvictor ?? nullEvictor;
}
+ isCompatible(version: string): boolean {
+ const compare = LibtoolVersion.compare(this.PROTOCOL_VERSION, version);
+ return compare?.compatible ?? false;
+ }
+
+ /**
+ * https://docs.taler.net/core/api-merchant.html#get--config
+ *
+ */
+ async getConfig() {
+ const url = new URL(`config`, this.baseUrl);
+ const resp = await this.httpLib.fetch(url.href, {
+ method: "GET",
+ });
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForMerchantConfig());
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
+ }
+
//
// Wallet API
//
@@ -77,9 +113,9 @@ class TalerMerchantInstanceHttpClient {
case HttpStatusCode.Ok:
return opSuccessFromHttp(resp, codecForClaimResponse());
case HttpStatusCode.Conflict:
- return opKnownHttpFailure(resp.status, resp)
+ return opKnownHttpFailure(resp.status, resp);
case HttpStatusCode.NotFound:
- return opKnownHttpFailure(resp.status, resp)
+ return opKnownHttpFailure(resp.status, resp);
default:
return opUnknownFailure(resp, await resp.text());
}
@@ -96,36 +132,70 @@ class TalerMerchantInstanceHttpClient {
body,
});
- ///
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForPaymentResponse());
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.PaymentRequired:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.RequestTimeout:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Gone:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.PreconditionFailed:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.BadGateway:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.GatewayTimeout:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-orders-$ORDER_ID
*/
- async getPaymentStatus(orderId: string, params: TalerMerchantApi.PaymentStatusRequestParams = {}) {
+ async getPaymentStatus(
+ orderId: string,
+ params: TalerMerchantApi.PaymentStatusRequestParams = {},
+ ) {
const url = new URL(`orders/${orderId}`, this.baseUrl);
if (params.allowRefundedForRepurchase !== undefined) {
- url.searchParams.set("allow_refunded_for_repurchase", params.allowRefundedForRepurchase ? "YES" : "NO")
+ url.searchParams.set(
+ "allow_refunded_for_repurchase",
+ params.allowRefundedForRepurchase ? "YES" : "NO",
+ );
}
if (params.awaitRefundObtained !== undefined) {
- url.searchParams.set("await_refund_obtained", params.allowRefundedForRepurchase ? "YES" : "NO")
+ url.searchParams.set(
+ "await_refund_obtained",
+ params.allowRefundedForRepurchase ? "YES" : "NO",
+ );
}
if (params.claimToken !== undefined) {
- url.searchParams.set("token", params.claimToken)
+ url.searchParams.set("token", params.claimToken);
}
if (params.contractTermHash !== undefined) {
- url.searchParams.set("h_contract", params.contractTermHash)
+ url.searchParams.set("h_contract", params.contractTermHash);
}
if (params.refund !== undefined) {
- url.searchParams.set("refund", params.refund)
+ url.searchParams.set("refund", params.refund);
}
if (params.sessionId !== undefined) {
- url.searchParams.set("session_id", params.sessionId)
+ url.searchParams.set("session_id", params.sessionId);
}
if (params.timeout !== undefined) {
- url.searchParams.set("timeout_ms", String(params.timeout))
+ url.searchParams.set("timeout_ms", String(params.timeout));
}
const resp = await this.httpLib.fetch(url.href, {
@@ -133,7 +203,23 @@ class TalerMerchantInstanceHttpClient {
// body,
});
- ///
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForStatusPaid());
+ case HttpStatusCode.Accepted:
+ return opSuccessFromHttp(resp, codecForStatusGoto());
+ // case HttpStatusCode.Found: not possible since content is not HTML
+ case HttpStatusCode.PaymentRequired:
+ return opSuccessFromHttp(resp, codecForStatusStatusUnpaid());
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotAcceptable:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
@@ -146,40 +232,87 @@ class TalerMerchantInstanceHttpClient {
method: "POST",
body,
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForPaidRefundStatusResponse());
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#aborting-incomplete-payments
*/
- async abortIncompletePayment(orderId: string, body: TalerMerchantApi.AbortRequest) {
+ async abortIncompletePayment(
+ orderId: string,
+ body: TalerMerchantApi.AbortRequest,
+ ) {
const url = new URL(`orders/${orderId}/abort`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
body,
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForAbortResponse());
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#obtaining-refunds
*/
- async obtainRefund(orderId: string, body: TalerMerchantApi.WalletRefundRequest) {
+ async obtainRefund(
+ orderId: string,
+ body: TalerMerchantApi.WalletRefundRequest,
+ ) {
const url = new URL(`orders/${orderId}/refund`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "POST",
body,
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForWalletRefundResponse());
+ case HttpStatusCode.BadRequest:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Forbidden:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
- //
+ //
// Management
//
/**
* https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-auth
*/
- async updateCurrentInstanceAuthentication(body: TalerMerchantApi.InstanceAuthConfigurationMessage) {
+ async updateCurrentInstanceAuthentication(
+ body: TalerMerchantApi.InstanceAuthConfigurationMessage,
+ ) {
const url = new URL(`private/auth`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -188,11 +321,19 @@ class TalerMerchantInstanceHttpClient {
});
//
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* Get the auth api agaisnt the current instance
- *
+ *
* https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCE]-private-token
* https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private-token
*/
@@ -201,20 +342,30 @@ class TalerMerchantInstanceHttpClient {
}
/**
- * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private
- */
- async updateCurrentInstance(body: TalerMerchantApi.InstanceReconfigurationMessage) {
+ * https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private
+ */
+ async updateCurrentInstance(
+ body: TalerMerchantApi.InstanceReconfigurationMessage,
+ ) {
const url = new URL(`private`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "PATCH",
body,
});
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private
- *
+ *
*/
async getCurrentInstance() {
const url = new URL(`private`, this.baseUrl);
@@ -222,43 +373,79 @@ class TalerMerchantInstanceHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForQueryInstancesResponse());
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
- * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private
- */
+ * https://docs.taler.net/core/api-merchant.html#delete-[-instances-$INSTANCE]-private
+ */
async deleteCurrentInstance(params: { purge?: boolean }) {
const url = new URL(`private`, this.baseUrl);
if (params.purge) {
- url.searchParams.set("purge", "YES")
+ url.searchParams.set("purge", "YES");
}
const resp = await this.httpLib.fetch(url.href, {
method: "DELETE",
});
+
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Unauthorized:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#get--instances-$INSTANCE-private-kyc
*/
- async getCurrentIntanceKycStatus(params: TalerMerchantApi.GetKycStatusRequestParams) {
+ async getCurrentIntanceKycStatus(
+ params: TalerMerchantApi.GetKycStatusRequestParams,
+ ) {
const url = new URL(`private/kyc`, this.baseUrl);
if (params.wireHash) {
- url.searchParams.set("h_wire", params.wireHash)
+ url.searchParams.set("h_wire", params.wireHash);
}
if (params.exchangeURL) {
- url.searchParams.set("exchange_url", params.exchangeURL)
+ url.searchParams.set("exchange_url", params.exchangeURL);
}
if (params.timeout) {
- url.searchParams.set("timeout_ms", String(params.timeout))
+ url.searchParams.set("timeout_ms", String(params.timeout));
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
+ switch (resp.status) {
+ case HttpStatusCode.Accepted:
+ return opSuccessFromHttp(resp, codecForAccountKycRedirects());
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.BadGateway:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.ServiceUnavailable:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
//
@@ -275,18 +462,40 @@ class TalerMerchantInstanceHttpClient {
method: "POST",
body,
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForAccountAddResponse());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-accounts-$H_WIRE
*/
- async updateAccount(wireAccount: string, body: TalerMerchantApi.AccountPatchDetails) {
+ async updateAccount(
+ wireAccount: string,
+ body: TalerMerchantApi.AccountPatchDetails,
+ ) {
const url = new URL(`private/accounts/${wireAccount}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "PATCH",
body,
});
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
@@ -298,6 +507,15 @@ class TalerMerchantInstanceHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForAccountsSummaryResponse());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
@@ -309,6 +527,15 @@ class TalerMerchantInstanceHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForBankAccountEntry());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
@@ -320,6 +547,15 @@ class TalerMerchantInstanceHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "DELETE",
});
+
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
//
@@ -336,29 +572,63 @@ class TalerMerchantInstanceHttpClient {
method: "POST",
body,
});
+
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-products-$PRODUCT_ID
*/
- async updateProduct(productId: string, body: TalerMerchantApi.ProductAddDetail) {
+ async updateProduct(
+ productId: string,
+ body: TalerMerchantApi.ProductAddDetail,
+ ) {
const url = new URL(`private/products/${productId}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "PATCH",
body,
});
+
+ switch (resp.status) {
+ case HttpStatusCode.NoContent:
+ return opEmptySuccess(resp);
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ case HttpStatusCode.Conflict:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
* https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-products
*/
- async listProducts() {
+ async listProducts(params?: PaginationParams) {
const url = new URL(`private/products`, this.baseUrl);
+ addMerchantPaginationParams(url, params);
+
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
+
+ switch (resp.status) {
+ case HttpStatusCode.Ok:
+ return opSuccessFromHttp(resp, codecForInventorySummaryResponse());
+ case HttpStatusCode.NotFound:
+ return opKnownHttpFailure(resp.status, resp);
+ default:
+ return opUnknownFailure(resp, await resp.text());
+ }
}
/**
@@ -417,31 +687,31 @@ class TalerMerchantInstanceHttpClient {
const url = new URL(`private/orders`, this.baseUrl);
if (params.date) {
- url.searchParams.set("date_s", String(params.date))
+ url.searchParams.set("date_s", String(params.date));
}
if (params.delta) {
- url.searchParams.set("delta", String(params.delta))
+ url.searchParams.set("delta", String(params.delta));
}
if (params.fulfillmentUrl) {
- url.searchParams.set("fulfillment_url", params.fulfillmentUrl)
+ url.searchParams.set("fulfillment_url", params.fulfillmentUrl);
}
if (params.paid) {
- url.searchParams.set("paid", "YES")
+ url.searchParams.set("paid", "YES");
}
if (params.refunded) {
- url.searchParams.set("refunded", "YES")
+ url.searchParams.set("refunded", "YES");
}
if (params.sessionId) {
- url.searchParams.set("session_id", params.sessionId)
+ url.searchParams.set("session_id", params.sessionId);
}
if (params.start) {
- url.searchParams.set("start", String(params.start))
+ url.searchParams.set("start", String(params.start));
}
if (params.timeout) {
- url.searchParams.set("timeout", String(params.timeout))
+ url.searchParams.set("timeout", String(params.timeout));
}
if (params.wired) {
- url.searchParams.set("wired", "YES")
+ url.searchParams.set("wired", "YES");
}
const resp = await this.httpLib.fetch(url.href, {
@@ -452,17 +722,20 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-orders-$ORDER_ID
*/
- async getOrder(orderId: string, params: TalerMerchantApi.GetOrderRequestParams = {}) {
+ async getOrder(
+ orderId: string,
+ params: TalerMerchantApi.GetOrderRequestParams = {},
+ ) {
const url = new URL(`private/orders/${orderId}`, this.baseUrl);
if (params.allowRefundedForRepurchase) {
- url.searchParams.set("allow_refunded_for_repurchase", "YES")
+ url.searchParams.set("allow_refunded_for_repurchase", "YES");
}
if (params.sessionId) {
- url.searchParams.set("session_id", params.sessionId)
+ url.searchParams.set("session_id", params.sessionId);
}
if (params.timeout) {
- url.searchParams.set("timeout_ms", String(params.timeout))
+ url.searchParams.set("timeout_ms", String(params.timeout));
}
const resp = await this.httpLib.fetch(url.href, {
@@ -493,7 +766,7 @@ class TalerMerchantInstanceHttpClient {
});
}
- //
+ //
// Refunds
//
@@ -528,26 +801,28 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-transfers
*/
- async listWireTransfers(params: TalerMerchantApi.ListWireTransferRequestParams = {}) {
+ async listWireTransfers(
+ params: TalerMerchantApi.ListWireTransferRequestParams = {},
+ ) {
const url = new URL(`private/transfers`, this.baseUrl);
if (params.after) {
- url.searchParams.set("after", String(params.after))
+ url.searchParams.set("after", String(params.after));
}
if (params.before) {
- url.searchParams.set("before", String(params.before))
+ url.searchParams.set("before", String(params.before));
}
if (params.limit) {
- url.searchParams.set("limit", String(params.limit))
+ url.searchParams.set("limit", String(params.limit));
}
if (params.offset) {
- url.searchParams.set("offset", String(params.offset))
+ url.searchParams.set("offset", String(params.offset));
}
if (params.paytoURI) {
- url.searchParams.set("payto_uri", params.paytoURI)
+ url.searchParams.set("payto_uri", params.paytoURI);
}
if (params.verified) {
- url.searchParams.set("verified", "YES")
+ url.searchParams.set("verified", "YES");
}
const resp = await this.httpLib.fetch(url.href, {
@@ -585,7 +860,10 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
*/
- async updateOtpDevice(deviceId: string, body: TalerMerchantApi.OtpDevicePatchDetails) {
+ async updateOtpDevice(
+ deviceId: string,
+ body: TalerMerchantApi.OtpDevicePatchDetails,
+ ) {
const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -608,19 +886,21 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#get-[-instances-$INSTANCE]-private-otp-devices-$DEVICE_ID
*/
- async getOtpDevice(deviceId: string, params: TalerMerchantApi.GetOtpDeviceRequestParams = {}) {
+ async getOtpDevice(
+ deviceId: string,
+ params: TalerMerchantApi.GetOtpDeviceRequestParams = {},
+ ) {
const url = new URL(`private/otp-devices/${deviceId}`, this.baseUrl);
if (params.faketime) {
- url.searchParams.set("faketime", String(params.faketime))
+ url.searchParams.set("faketime", String(params.faketime));
}
if (params.price) {
- url.searchParams.set("price", params.price)
+ url.searchParams.set("price", params.price);
}
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
-
}
/**
@@ -653,7 +933,10 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCE]-private-templates-$TEMPLATE_ID
*/
- async updateTemplate(templateId: string, body: TalerMerchantApi.TemplatePatchDetails) {
+ async updateTemplate(
+ templateId: string,
+ body: TalerMerchantApi.TemplatePatchDetails,
+ ) {
const url = new URL(`private/templates/${templateId}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -704,13 +987,15 @@ class TalerMerchantInstanceHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
-
}
/**
* https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-templates-$TEMPLATE_ID
*/
- async useTemplateCreateOrder(templateId: string, body: TalerMerchantApi.UsingTemplateDetails) {
+ async useTemplateCreateOrder(
+ templateId: string,
+ body: TalerMerchantApi.UsingTemplateDetails,
+ ) {
const url = new URL(`templates/${templateId}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -723,7 +1008,6 @@ class TalerMerchantInstanceHttpClient {
// Webhooks
//
-
/**
* https://docs.taler.net/core/api-merchant.html#post-[-instances-$INSTANCES]-private-webhooks
*/
@@ -739,7 +1023,10 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCES]-private-webhooks-$WEBHOOK_ID
*/
- async updateWebhook(webhookId: string, body: TalerMerchantApi.WebhookPatchDetails) {
+ async updateWebhook(
+ webhookId: string,
+ body: TalerMerchantApi.WebhookPatchDetails,
+ ) {
const url = new URL(`private/webhooks/${webhookId}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -800,7 +1087,10 @@ class TalerMerchantInstanceHttpClient {
/**
* https://docs.taler.net/core/api-merchant.html#patch-[-instances-$INSTANCES]-private-tokenfamilies-$TOKEN_FAMILY_SLUG
*/
- async updateTokenFamily(tokenSlug: string,body: TalerMerchantApi.TokenFamilyCreateRequest) {
+ async updateTokenFamily(
+ tokenSlug: string,
+ body: TalerMerchantApi.TokenFamilyCreateRequest,
+ ) {
const url = new URL(`private/tokenfamilies/${tokenSlug}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -829,7 +1119,6 @@ class TalerMerchantInstanceHttpClient {
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
-
}
/**
@@ -842,49 +1131,21 @@ class TalerMerchantInstanceHttpClient {
method: "DELETE",
});
}
-
}
export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttpClient {
- public readonly PROTOCOL_VERSION = "10:0:6";
-
- httpLib: HttpRequestLibrary;
- cacheEvictor: CacheEvictor<TalerMerchantCacheEviction>;
constructor(
readonly baseUrl: string,
httpClient?: HttpRequestLibrary,
cacheEvictor?: CacheEvictor<TalerMerchantCacheEviction>,
) {
- super(baseUrl, httpClient, cacheEvictor)
- }
-
- isCompatible(version: string): boolean {
- const compare = LibtoolVersion.compare(this.PROTOCOL_VERSION, version);
- return compare?.compatible ?? false;
+ super(baseUrl, httpClient, cacheEvictor);
}
getSubInstanceApi(instanceId: string) {
- return new URL(`instances/${instanceId}`, this.baseUrl)
- }
-
- /**
- * https://docs.taler.net/core/api-merchant.html#get--config
- *
- */
- async getConfig() {
- const url = new URL(`config`, this.baseUrl);
- const resp = await this.httpLib.fetch(url.href, {
- method: "GET",
- });
- switch (resp.status) {
- case HttpStatusCode.Ok:
- return opSuccessFromHttp(resp, codecForMerchantConfig());
- default:
- return opUnknownFailure(resp, await resp.text());
- }
+ return new URL(`instances/${instanceId}`, this.baseUrl);
}
-
//
// Instance Management
//
@@ -906,7 +1167,9 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
/**
* https://docs.taler.net/core/api-merchant.html#post--management-instances-$INSTANCE-auth
*/
- async updateInstanceAuthentication(body: TalerMerchantApi.InstanceAuthConfigurationMessage) {
+ async updateInstanceAuthentication(
+ body: TalerMerchantApi.InstanceAuthConfigurationMessage,
+ ) {
const url = new URL(`management/instances`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
@@ -917,19 +1180,19 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
//
}
-
/**
* https://docs.taler.net/core/api-merchant.html#patch--management-instances-$INSTANCE
*/
- async updateInstance(isntanceId: string, body: TalerMerchantApi.InstanceReconfigurationMessage) {
+ async updateInstance(
+ isntanceId: string,
+ body: TalerMerchantApi.InstanceReconfigurationMessage,
+ ) {
const url = new URL(`management/instances/${isntanceId}`, this.baseUrl);
const resp = await this.httpLib.fetch(url.href, {
method: "PATCH",
body,
});
-
-
}
/**
@@ -941,12 +1204,11 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
-
}
/**
* https://docs.taler.net/core/api-merchant.html#get--management-instances-$INSTANCE
- *
+ *
*/
async getInstance(instanceId: string) {
const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
@@ -959,11 +1221,11 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
/**
* https://docs.taler.net/core/api-merchant.html#delete--management-instances-$INSTANCE
*/
- async deleteInstance(instanceId: string, params: {purge?: boolean} = {}) {
+ async deleteInstance(instanceId: string, params: { purge?: boolean } = {}) {
const url = new URL(`management/instances/${instanceId}`, this.baseUrl);
if (params.purge) {
- url.searchParams.set("purge", "YES")
+ url.searchParams.set("purge", "YES");
}
const resp = await this.httpLib.fetch(url.href, {
@@ -974,25 +1236,24 @@ export class TalerMerchantManagementHttpClient extends TalerMerchantInstanceHttp
/**
* https://docs.taler.net/core/api-merchant.html#get--management-instances-$INSTANCE-kyc
*/
- async getIntanceKycStatus(instanceId: string, params: TalerMerchantApi.GetKycStatusRequestParams) {
+ async getIntanceKycStatus(
+ instanceId: string,
+ params: TalerMerchantApi.GetKycStatusRequestParams,
+ ) {
const url = new URL(`management/instances/${instanceId}/kyc`, this.baseUrl);
if (params.wireHash) {
- url.searchParams.set("h_wire", params.wireHash)
+ url.searchParams.set("h_wire", params.wireHash);
}
if (params.exchangeURL) {
- url.searchParams.set("exchange_url", params.exchangeURL)
+ url.searchParams.set("exchange_url", params.exchangeURL);
}
if (params.timeout) {
- url.searchParams.set("timeout_ms", String(params.timeout))
+ url.searchParams.set("timeout_ms", String(params.timeout));
}
-
+
const resp = await this.httpLib.fetch(url.href, {
method: "GET",
});
}
-
-
-
-
}
diff --git a/packages/taler-util/src/http-client/types.ts b/packages/taler-util/src/http-client/types.ts
index 67ac289d6..7e4e2f84c 100644
--- a/packages/taler-util/src/http-client/types.ts
+++ b/packages/taler-util/src/http-client/types.ts
@@ -6,6 +6,7 @@ import {
buildCodecForUnion,
codecForAny,
codecForBoolean,
+ codecForConstNumber,
codecForConstString,
codecForEither,
codecForList,
@@ -15,12 +16,18 @@ import {
codecOptional,
} from "../codec.js";
import { PaytoString, codecForPaytoString } from "../payto.js";
-import { AmountString, MerchantContractTerms, codecForMerchantContractTerms } from "../taler-types.js";
+import {
+ AmountString,
+ MerchantContractTerms,
+ codecForLocation,
+ codecForMerchantContractTerms,
+} from "../taler-types.js";
import { TalerActionString, codecForTalerActionString } from "../taleruri.js";
import {
AbsoluteTime,
TalerProtocolDuration,
TalerProtocolTimestamp,
+ codecForDuration,
codecForTimestamp,
} from "../time.js";
@@ -315,9 +322,216 @@ export const codecForMerchantConfig =
export const codecForClaimResponse =
(): Codec<TalerMerchantApi.ClaimResponse> =>
buildCodecForObject<TalerMerchantApi.ClaimResponse>()
- .property("contract_terms", codecForMerchantContractTerms())
- .property("sig", codecForString())
- .build("TalerMerchantApi.ClaimResponse");
+ .property("contract_terms", codecForMerchantContractTerms())
+ .property("sig", codecForString())
+ .build("TalerMerchantApi.ClaimResponse");
+
+export const codecForPaymentResponse =
+ (): Codec<TalerMerchantApi.PaymentResponse> =>
+ buildCodecForObject<TalerMerchantApi.PaymentResponse>()
+ .property("pos_confirmation", codecOptional(codecForString()))
+ .property("sig", codecForString())
+ .build("TalerMerchantApi.PaymentResponse");
+
+export const codecForStatusPaid = (): Codec<TalerMerchantApi.StatusPaid> =>
+ buildCodecForObject<TalerMerchantApi.StatusPaid>()
+ .property("refund_amount", codecForAmountString())
+ .property("refund_pending", codecForBoolean())
+ .property("refund_taken", codecForAmountString())
+ .property("refunded", codecForBoolean())
+ .property("type", codecForConstString("paid"))
+ .build("TalerMerchantApi.StatusPaid");
+
+export const codecForStatusGoto =
+ (): Codec<TalerMerchantApi.StatusGotoResponse> =>
+ buildCodecForObject<TalerMerchantApi.StatusGotoResponse>()
+ .property("public_reorder_url", codecForURL())
+ .property("type", codecForConstString("goto"))
+ .build("TalerMerchantApi.StatusGotoResponse");
+
+export const codecForStatusStatusUnpaid =
+ (): Codec<TalerMerchantApi.StatusUnpaidResponse> =>
+ buildCodecForObject<TalerMerchantApi.StatusUnpaidResponse>()
+ .property("type", codecForConstString("unpaid"))
+ .property("already_paid_order_id", codecOptional(codecForString()))
+ .property("fulfillment_url", codecOptional(codecForString()))
+ .property("taler_pay_uri", codecForString())
+ .build("TalerMerchantApi.PaymentResponse");
+
+export const codecForPaidRefundStatusResponse =
+ (): Codec<TalerMerchantApi.PaidRefundStatusResponse> =>
+ buildCodecForObject<TalerMerchantApi.PaidRefundStatusResponse>()
+ .property("pos_confirmation", codecOptional(codecForString()))
+ .property("refunded", codecForBoolean())
+ .build("TalerMerchantApi.PaidRefundStatusResponse");
+
+export const codecForMerchantAbortPayRefundSuccessStatus =
+ (): Codec<TalerMerchantApi.MerchantAbortPayRefundSuccessStatus> =>
+ buildCodecForObject<TalerMerchantApi.MerchantAbortPayRefundSuccessStatus>()
+ .property("exchange_pub", codecForString())
+ .property("exchange_sig", codecForString())
+ .property("exchange_status", codecForConstNumber(200))
+ .property("type", codecForConstString("success"))
+ .build("TalerMerchantApi.MerchantAbortPayRefundSuccessStatus");
+
+export const codecForMerchantAbortPayRefundFailureStatus =
+ (): Codec<TalerMerchantApi.MerchantAbortPayRefundFailureStatus> =>
+ buildCodecForObject<TalerMerchantApi.MerchantAbortPayRefundFailureStatus>()
+ .property("exchange_code", codecForNumber())
+ .property("exchange_reply", codecForAny())
+ .property("exchange_status", codecForNumber())
+ .property("type", codecForConstString("failure"))
+ .build("TalerMerchantApi.MerchantAbortPayRefundFailureStatus");
+
+export const codecForMerchantAbortPayRefundStatus =
+ (): Codec<TalerMerchantApi.MerchantAbortPayRefundStatus> =>
+ buildCodecForUnion<TalerMerchantApi.MerchantAbortPayRefundStatus>()
+ .discriminateOn("type")
+ .alternative("success", codecForMerchantAbortPayRefundSuccessStatus())
+ .alternative("failure", codecForMerchantAbortPayRefundFailureStatus())
+ .build("TalerMerchantApi.MerchantAbortPayRefundStatus");
+
+export const codecForAbortResponse =
+ (): Codec<TalerMerchantApi.AbortResponse> =>
+ buildCodecForObject<TalerMerchantApi.AbortResponse>()
+ .property("refunds", codecForList(codecForMerchantAbortPayRefundStatus()))
+ .build("TalerMerchantApi.AbortResponse");
+
+export const codecForWalletRefundResponse =
+ (): Codec<TalerMerchantApi.WalletRefundResponse> =>
+ buildCodecForObject<TalerMerchantApi.WalletRefundResponse>()
+ .property("merchant_pub", codecForString())
+ .property("refund_amount", codecForAmountString())
+ .property("refunds", codecForList(codecForMerchantCoinRefundStatus()))
+ .build("TalerMerchantApi.AbortResponse");
+
+export const codecForMerchantCoinRefundSuccessStatus =
+ (): Codec<TalerMerchantApi.MerchantCoinRefundSuccessStatus> =>
+ buildCodecForObject<TalerMerchantApi.MerchantCoinRefundSuccessStatus>()
+ .property("type", codecForConstString("success"))
+ .property("coin_pub", codecForString())
+ .property("exchange_status", codecForConstNumber(200))
+ .property("exchange_sig", codecForString())
+ .property("rtransaction_id", codecForNumber())
+ .property("refund_amount", codecForAmountString())
+ .property("exchange_pub", codecForString())
+ .property("execution_time", codecForTimestamp)
+ .build("TalerMerchantApi.MerchantCoinRefundSuccessStatus");
+
+export const codecForMerchantCoinRefundFailureStatus =
+ (): Codec<TalerMerchantApi.MerchantCoinRefundFailureStatus> =>
+ buildCodecForObject<TalerMerchantApi.MerchantCoinRefundFailureStatus>()
+ .property("type", codecForConstString("failure"))
+ .property("coin_pub", codecForString())
+ .property("exchange_status", codecForNumber())
+ .property("rtransaction_id", codecForNumber())
+ .property("refund_amount", codecForAmountString())
+ .property("exchange_code", codecOptional(codecForNumber()))
+ .property("exchange_reply", codecOptional(codecForAny()))
+ .property("execution_time", codecForTimestamp)
+ .build("TalerMerchantApi.MerchantCoinRefundFailureStatus");
+
+export const codecForMerchantCoinRefundStatus =
+ (): Codec<TalerMerchantApi.MerchantCoinRefundStatus> =>
+ buildCodecForUnion<TalerMerchantApi.MerchantCoinRefundStatus>()
+ .discriminateOn("type")
+ .alternative("success", codecForMerchantCoinRefundSuccessStatus())
+ .alternative("failure", codecForMerchantCoinRefundFailureStatus())
+ .build("TalerMerchantApi.MerchantCoinRefundStatus");
+
+export const codecForQueryInstancesResponse =
+ (): Codec<TalerMerchantApi.QueryInstancesResponse> =>
+ buildCodecForObject<TalerMerchantApi.QueryInstancesResponse>()
+ .property("name", codecForString())
+ .property("user_type", codecForString())
+ .property("email", codecOptional(codecForString()))
+ .property("website", codecOptional(codecForString()))
+ .property("logo", codecOptional(codecForString()))
+ .property("merchant_pub", codecForString())
+ .property("address", codecForLocation())
+ .property("jurisdiction", codecForLocation())
+ .property("use_stefan", codecForBoolean())
+ .property("default_wire_transfer_delay", codecForDuration)
+ .property("default_pay_delay", codecForDuration)
+ .property(
+ "auth",
+ buildCodecForObject<{
+ type: "external" | "token";
+ }>()
+ .property(
+ "type",
+ codecForEither(
+ codecForConstString("token"),
+ codecForConstString("external"),
+ ),
+ )
+ .build("TalerMerchantApi.QueryInstancesResponse.auth"),
+ )
+ .build("TalerMerchantApi.QueryInstancesResponse");
+
+export const codecForAccountKycRedirects =
+ (): Codec<TalerMerchantApi.AccountKycRedirects> =>
+ buildCodecForObject<TalerMerchantApi.AccountKycRedirects>()
+ .property(
+ "pending_kycs",
+ codecForList(codecForMerchantAccountKycRedirect()),
+ )
+ .property("timeout_kycs", codecForList(codecForExchangeKycTimeout()))
+
+ .build("TalerMerchantApi.AccountKycRedirects");
+
+export const codecForMerchantAccountKycRedirect =
+ (): Codec<TalerMerchantApi.MerchantAccountKycRedirect> =>
+ buildCodecForObject<TalerMerchantApi.MerchantAccountKycRedirect>()
+ .property("kyc_url", codecForURL())
+ .property("aml_status", codecForNumber())
+ .property("exchange_url", codecForURL())
+ .property("payto_uri", codecForPaytoString())
+ .build("TalerMerchantApi.MerchantAccountKycRedirect");
+
+export const codecForExchangeKycTimeout =
+ (): Codec<TalerMerchantApi.ExchangeKycTimeout> =>
+ buildCodecForObject<TalerMerchantApi.ExchangeKycTimeout>()
+ .property("exchange_url", codecForURL())
+ .property("exchange_code", codecForNumber())
+ .property("exchange_http_status", codecForNumber())
+ .build("TalerMerchantApi.ExchangeKycTimeout");
+
+export const codecForAccountAddResponse =
+ (): Codec<TalerMerchantApi.AccountAddResponse> =>
+ buildCodecForObject<TalerMerchantApi.AccountAddResponse>()
+ .property("h_wire", codecForString())
+ .property("salt", codecForString())
+ .build("TalerMerchantApi.AccountAddResponse");
+
+export const codecForAccountsSummaryResponse =
+ (): Codec<TalerMerchantApi.AccountsSummaryResponse> =>
+ buildCodecForObject<TalerMerchantApi.AccountsSummaryResponse>()
+ .property("accounts", codecForList(codecForBankAccountEntry()))
+ .build("TalerMerchantApi.AccountsSummaryResponse");
+
+export const codecForBankAccountEntry =
+ (): Codec<TalerMerchantApi.BankAccountEntry> =>
+ buildCodecForObject<TalerMerchantApi.BankAccountEntry>()
+ .property("payto_uri", codecForPaytoString())
+ .property("h_wire", codecForString())
+ .property("salt", codecForString())
+ .property("credit_facade_url", codecForURL())
+ .property("active", codecForBoolean())
+ .build("TalerMerchantApi.BankAccountEntry");
+
+export const codecForInventorySummaryResponse =
+ (): Codec<TalerMerchantApi.InventorySummaryResponse> =>
+ buildCodecForObject<TalerMerchantApi.InventorySummaryResponse>()
+ .property("products", codecForList(codecForInventoryEntry()))
+ .build("TalerMerchantApi.InventorySummaryResponse");
+
+export const codecForInventoryEntry =
+ (): Codec<TalerMerchantApi.InventoryEntry> =>
+ buildCodecForObject<TalerMerchantApi.InventoryEntry>()
+ .property("product_id", codecForString())
+ .property("product_serial", codecForNumber())
+ .build("TalerMerchantApi.InventoryEntry");
export const codecForExchangeConfig =
(): Codec<TalerExchangeApi.ExchangeVersionResponse> =>
@@ -2477,7 +2691,6 @@ export namespace TalerMerchantApi {
export interface ClaimResponse {
// Contract terms of the claimed order
contract_terms: MerchantContractTerms;
-
// Signature by the merchant over the contract terms.
sig: EddsaSignature;
@@ -2647,7 +2860,9 @@ export namespace TalerMerchantApi {
exchange_url: string;
}
- interface StatusPaid {
+ export interface StatusPaid {
+ type: "paid";
+
// Was the payment refunded (even partially, via refund or abort)?
refunded: boolean;
@@ -2660,14 +2875,16 @@ export namespace TalerMerchantApi {
// Amount that already taken by the wallet.
refund_taken: AmountString;
}
- interface StatusGotoResponse {
+ export interface StatusGotoResponse {
+ type: "goto";
// The client should go to the reorder URL, there a fresh
// order might be created as this one is taken by another
// customer or wallet (or repurchase detection logic may
// apply).
public_reorder_url: string;
}
- interface StatusUnpaidResponse {
+ export interface StatusUnpaidResponse {
+ type: "unpaid";
// URI that the wallet must process to complete the payment.
taler_pay_uri: string;
@@ -2680,7 +2897,7 @@ export namespace TalerMerchantApi {
already_paid_order_id?: string;
}
- interface PaidRefundStatusResponse {
+ export interface PaidRefundStatusResponse {
// Text to be shown to the point-of-sale staff as a proof of
// payment (present only if reusable OTP algorithm is used).
pos_confirmation?: string;
@@ -2726,18 +2943,18 @@ export namespace TalerMerchantApi {
// URL of the exchange this coin was withdrawn from.
exchange_url: string;
}
- interface AbortResponse {
+ export interface AbortResponse {
// List of refund responses about the coins that the wallet
// requested an abort for. In the same order as the coins
// from the original request.
// The rtransaction_id is implied to be 0.
refunds: MerchantAbortPayRefundStatus[];
}
- type MerchantAbortPayRefundStatus =
+ export type MerchantAbortPayRefundStatus =
| MerchantAbortPayRefundSuccessStatus
| MerchantAbortPayRefundFailureStatus;
// Details about why a refund failed.
- interface MerchantAbortPayRefundFailureStatus {
+ export interface MerchantAbortPayRefundFailureStatus {
// Used as tag for the sum type RefundStatus sum type.
type: "failure";
@@ -2753,7 +2970,7 @@ export namespace TalerMerchantApi {
// Additional details needed to verify the refund confirmation signature
// (h_contract_terms and merchant_pub) are already known
// to the wallet and thus not included.
- interface MerchantAbortPayRefundSuccessStatus {
+ export interface MerchantAbortPayRefundSuccessStatus {
// Used as tag for the sum type MerchantCoinRefundStatus sum type.
type: "success";
@@ -2777,7 +2994,7 @@ export namespace TalerMerchantApi {
// wallet/customer).
h_contract: HashCode;
}
- interface WalletRefundResponse {
+ export interface WalletRefundResponse {
// Amount that was refunded in total.
refund_amount: AmountString;
@@ -2787,11 +3004,11 @@ export namespace TalerMerchantApi {
// Public key of the merchant.
merchant_pub: EddsaPublicKey;
}
- type MerchantCoinRefundStatus =
+ export type MerchantCoinRefundStatus =
| MerchantCoinRefundSuccessStatus
| MerchantCoinRefundFailureStatus;
// Details about why a refund failed.
- interface MerchantCoinRefundFailureStatus {
+ export interface MerchantCoinRefundFailureStatus {
// Used as tag for the sum type RefundStatus sum type.
type: "failure";
@@ -2821,7 +3038,7 @@ export namespace TalerMerchantApi {
// Additional details needed to verify the refund confirmation signature
// (h_contract_terms and merchant_pub) are already known
// to the wallet and thus not included.
- interface MerchantCoinRefundSuccessStatus {
+ export interface MerchantCoinRefundSuccessStatus {
// Used as tag for the sum type MerchantCoinRefundStatus sum type.
type: "success";
@@ -3031,7 +3248,7 @@ export namespace TalerMerchantApi {
deleted: boolean;
}
- interface QueryInstancesResponse {
+ export interface QueryInstancesResponse {
// Merchant name corresponding to this instance.
name: string;
@@ -3079,7 +3296,7 @@ export namespace TalerMerchantApi {
};
}
- interface AccountKycRedirects {
+ export interface AccountKycRedirects {
// Array of pending KYCs.
pending_kycs: MerchantAccountKycRedirect[];
@@ -3087,7 +3304,7 @@ export namespace TalerMerchantApi {
timeout_kycs: ExchangeKycTimeout[];
}
- interface MerchantAccountKycRedirect {
+ export interface MerchantAccountKycRedirect {
// URL that the user should open in a browser to
// proceed with the KYC process (as returned
// by the exchange's /kyc-check/ endpoint).
@@ -3105,7 +3322,7 @@ export namespace TalerMerchantApi {
payto_uri: PaytoString;
}
- interface ExchangeKycTimeout {
+ export interface ExchangeKycTimeout {
// Base URL of the exchange this is about.
exchange_url: string;
@@ -3135,11 +3352,13 @@ export namespace TalerMerchantApi {
credit_facade_credentials?: FacadeCredentials;
}
- type FacadeCredentials = NoFacadeCredentials | BasicAuthFacadeCredentials;
- interface NoFacadeCredentials {
+ export type FacadeCredentials =
+ | NoFacadeCredentials
+ | BasicAuthFacadeCredentials;
+ export interface NoFacadeCredentials {
type: "none";
}
- interface BasicAuthFacadeCredentials {
+ export interface BasicAuthFacadeCredentials {
type: "basic";
// Username to use to authenticate
@@ -3148,7 +3367,7 @@ export namespace TalerMerchantApi {
// Password to use to authenticate
password: string;
}
- interface AccountAddResponse {
+ export interface AccountAddResponse {
// Hash over the wire details (including over the salt).
h_wire: HashCode;
@@ -3171,11 +3390,11 @@ export namespace TalerMerchantApi {
credit_facade_credentials?: FacadeCredentials;
}
- interface AccountsSummaryResponse {
+ export interface AccountsSummaryResponse {
// List of accounts that are known for the instance.
accounts: BankAccountEntry[];
}
- interface BankAccountEntry {
+ export interface BankAccountEntry {
// payto:// URI of the account.
payto_uri: PaytoString;
@@ -3278,17 +3497,19 @@ export namespace TalerMerchantApi {
minimum_age?: Integer;
}
- interface InventorySummaryResponse {
+ export interface InventorySummaryResponse {
// List of products that are present in the inventory.
products: InventoryEntry[];
}
- interface InventoryEntry {
+ export interface InventoryEntry {
// Product identifier, as found in the product.
product_id: string;
+ // product_serial_id of the product in the database.
+ product_serial: Integer;
}
- interface ProductDetail {
+ export interface ProductDetail {
// Human-readable product description.
description: string;
diff --git a/packages/taler-util/src/http-client/utils.ts b/packages/taler-util/src/http-client/utils.ts
index f925a5610..dbfe64796 100644
--- a/packages/taler-util/src/http-client/utils.ts
+++ b/packages/taler-util/src/http-client/utils.ts
@@ -59,6 +59,21 @@ export function addPaginationParams(url: URL, pagination?: PaginationParams) {
url.searchParams.set("delta", String(order * limit));
}
+export function addMerchantPaginationParams(url: URL, pagination?: PaginationParams) {
+ if (!pagination) return;
+ if (pagination.offset) {
+ url.searchParams.set("offset", pagination.offset);
+ }
+ const order = !pagination || pagination.order === "asc" ? 1 : -1;
+ const limit =
+ !pagination || !pagination.limit || pagination.limit === 0
+ ? 5
+ : Math.abs(pagination.limit);
+ //always send delta
+ url.searchParams.set("limit", String(order * limit));
+}
+
+
export function addLongPollingParam(url: URL, param?: LongPollParams) {
if (!param) return;
if (param.timeoutMs) {