towards consuming new merchant API
This commit is contained in:
parent
dd2efc3d78
commit
f4a8702b3c
@ -336,7 +336,7 @@ export class CryptoImplementation {
|
|||||||
const d = buildSigPS(SignaturePurpose.WALLET_COIN_DEPOSIT)
|
const d = buildSigPS(SignaturePurpose.WALLET_COIN_DEPOSIT)
|
||||||
.put(decodeCrock(depositInfo.contractTermsHash))
|
.put(decodeCrock(depositInfo.contractTermsHash))
|
||||||
.put(decodeCrock(depositInfo.wireInfoHash))
|
.put(decodeCrock(depositInfo.wireInfoHash))
|
||||||
.put(hash(decodeCrock(depositInfo.denomPub)))
|
.put(decodeCrock(depositInfo.denomPubHash))
|
||||||
.put(timestampRoundedToBuffer(depositInfo.timestamp))
|
.put(timestampRoundedToBuffer(depositInfo.timestamp))
|
||||||
.put(timestampRoundedToBuffer(depositInfo.refundDeadline))
|
.put(timestampRoundedToBuffer(depositInfo.refundDeadline))
|
||||||
.put(amountToBuffer(depositInfo.spendAmount))
|
.put(amountToBuffer(depositInfo.spendAmount))
|
||||||
@ -350,7 +350,7 @@ export class CryptoImplementation {
|
|||||||
coin_pub: depositInfo.coinPub,
|
coin_pub: depositInfo.coinPub,
|
||||||
coin_sig: encodeCrock(coinSig),
|
coin_sig: encodeCrock(coinSig),
|
||||||
contribution: Amounts.stringify(depositInfo.spendAmount),
|
contribution: Amounts.stringify(depositInfo.spendAmount),
|
||||||
denom_pub: depositInfo.denomPub,
|
h_denom: depositInfo.denomPubHash,
|
||||||
exchange_url: depositInfo.exchangeBaseUrl,
|
exchange_url: depositInfo.exchangeBaseUrl,
|
||||||
ub_sig: depositInfo.denomSig,
|
ub_sig: depositInfo.denomSig,
|
||||||
};
|
};
|
||||||
|
@ -25,6 +25,7 @@ import { NodeHttpLib } from "./NodeHttpLib";
|
|||||||
import { Wallet } from "../wallet";
|
import { Wallet } from "../wallet";
|
||||||
import { Configuration } from "../util/talerconfig";
|
import { Configuration } from "../util/talerconfig";
|
||||||
import { Amounts, AmountJson } from "../util/amounts";
|
import { Amounts, AmountJson } from "../util/amounts";
|
||||||
|
import { OperationFailedAndReportedError, OperationFailedError } from "../operations/errors";
|
||||||
|
|
||||||
const logger = new Logger("integrationtest.ts");
|
const logger = new Logger("integrationtest.ts");
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ import {
|
|||||||
setupRefreshPlanchet,
|
setupRefreshPlanchet,
|
||||||
encodeCrock,
|
encodeCrock,
|
||||||
} from "../crypto/talerCrypto";
|
} from "../crypto/talerCrypto";
|
||||||
import { OperationFailedAndReportedError } from "../operations/errors";
|
import { OperationFailedAndReportedError, OperationFailedError } from "../operations/errors";
|
||||||
import { Bank } from "./bank";
|
import { Bank } from "./bank";
|
||||||
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
|
import { classifyTalerUri, TalerUriType } from "../util/taleruri";
|
||||||
import { Configuration } from "../util/talerconfig";
|
import { Configuration } from "../util/talerconfig";
|
||||||
@ -97,7 +97,6 @@ async function doPay(
|
|||||||
|
|
||||||
if (pay) {
|
if (pay) {
|
||||||
await wallet.confirmPay(result.proposalId, undefined);
|
await wallet.confirmPay(result.proposalId, undefined);
|
||||||
console.log("paid!");
|
|
||||||
} else {
|
} else {
|
||||||
console.log("not paying");
|
console.log("not paying");
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ export async function getBalancesInsideTransaction(
|
|||||||
if (t.timestampFirstSuccessfulPay) {
|
if (t.timestampFirstSuccessfulPay) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const c of t.payReq.coins) {
|
for (const c of t.coinDepositPermissions) {
|
||||||
addTo(
|
addTo(
|
||||||
balanceStore,
|
balanceStore,
|
||||||
"pendingPayment",
|
"pendingPayment",
|
||||||
|
@ -24,8 +24,6 @@
|
|||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { OperationError } from "../types/walletTypes";
|
import { OperationError } from "../types/walletTypes";
|
||||||
import { HttpResponse } from "../util/http";
|
|
||||||
import { Codec } from "../util/codec";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This exception is there to let the caller know that an error happened,
|
* This exception is there to let the caller know that an error happened,
|
||||||
|
@ -246,7 +246,7 @@ export async function getHistory(
|
|||||||
contribution: string;
|
contribution: string;
|
||||||
denomPub: string;
|
denomPub: string;
|
||||||
}[] = [];
|
}[] = [];
|
||||||
for (const x of purchase.payReq.coins) {
|
for (const x of purchase.coinDepositPermissions) {
|
||||||
const c = await tx.get(Stores.coins, x.coin_pub);
|
const c = await tx.get(Stores.coins, x.coin_pub);
|
||||||
if (!c) {
|
if (!c) {
|
||||||
// FIXME: what to do here??
|
// FIXME: what to do here??
|
||||||
@ -269,7 +269,7 @@ export async function getHistory(
|
|||||||
verboseDetails = { coins };
|
verboseDetails = { coins };
|
||||||
}
|
}
|
||||||
const amountPaidWithFees = Amounts.sum(
|
const amountPaidWithFees = Amounts.sum(
|
||||||
purchase.payReq.coins.map((x) =>
|
purchase.coinDepositPermissions.map((x) =>
|
||||||
Amounts.parseOrThrow(x.contribution),
|
Amounts.parseOrThrow(x.contribution),
|
||||||
),
|
),
|
||||||
).amount;
|
).amount;
|
||||||
@ -280,7 +280,7 @@ export async function getHistory(
|
|||||||
replay: pe.isReplay,
|
replay: pe.isReplay,
|
||||||
sessionId: pe.sessionId,
|
sessionId: pe.sessionId,
|
||||||
timestamp: pe.timestamp,
|
timestamp: pe.timestamp,
|
||||||
numCoins: purchase.payReq.coins.length,
|
numCoins: purchase.coinDepositPermissions.length,
|
||||||
amountPaidWithFees: Amounts.stringify(amountPaidWithFees),
|
amountPaidWithFees: Amounts.stringify(amountPaidWithFees),
|
||||||
verboseDetails,
|
verboseDetails,
|
||||||
});
|
});
|
||||||
|
@ -42,6 +42,7 @@ import {
|
|||||||
codecForProposal,
|
codecForProposal,
|
||||||
codecForContractTerms,
|
codecForContractTerms,
|
||||||
CoinDepositPermission,
|
CoinDepositPermission,
|
||||||
|
codecForMerchantPayResponse,
|
||||||
} from "../types/talerTypes";
|
} from "../types/talerTypes";
|
||||||
import {
|
import {
|
||||||
ConfirmPayResult,
|
ConfirmPayResult,
|
||||||
@ -431,12 +432,6 @@ async function recordConfirmPay(
|
|||||||
sessionId = proposal.downloadSessionId;
|
sessionId = proposal.downloadSessionId;
|
||||||
}
|
}
|
||||||
logger.trace(`recording payment with session ID ${sessionId}`);
|
logger.trace(`recording payment with session ID ${sessionId}`);
|
||||||
const payReq: PayReq = {
|
|
||||||
coins: coinDepositPermissions,
|
|
||||||
merchant_pub: d.contractData.merchantPub,
|
|
||||||
mode: "pay",
|
|
||||||
order_id: d.contractData.orderId,
|
|
||||||
};
|
|
||||||
const payCostInfo = await getTotalPaymentCost(ws, coinSelection);
|
const payCostInfo = await getTotalPaymentCost(ws, coinSelection);
|
||||||
const t: PurchaseRecord = {
|
const t: PurchaseRecord = {
|
||||||
abortDone: false,
|
abortDone: false,
|
||||||
@ -445,8 +440,8 @@ async function recordConfirmPay(
|
|||||||
contractData: d.contractData,
|
contractData: d.contractData,
|
||||||
lastSessionId: sessionId,
|
lastSessionId: sessionId,
|
||||||
payCoinSelection: coinSelection,
|
payCoinSelection: coinSelection,
|
||||||
payReq,
|
|
||||||
payCostInfo,
|
payCostInfo,
|
||||||
|
coinDepositPermissions,
|
||||||
timestampAccept: getTimestampNow(),
|
timestampAccept: getTimestampNow(),
|
||||||
timestampLastRefundStatus: undefined,
|
timestampLastRefundStatus: undefined,
|
||||||
proposalId: proposal.proposalId,
|
proposalId: proposal.proposalId,
|
||||||
@ -609,7 +604,6 @@ async function processDownloadProposalImpl(
|
|||||||
).href;
|
).href;
|
||||||
logger.trace("downloading contract from '" + orderClaimUrl + "'");
|
logger.trace("downloading contract from '" + orderClaimUrl + "'");
|
||||||
|
|
||||||
|
|
||||||
const proposalResp = await httpPostTalerJson({
|
const proposalResp = await httpPostTalerJson({
|
||||||
url: orderClaimUrl,
|
url: orderClaimUrl,
|
||||||
body: {
|
body: {
|
||||||
@ -777,26 +771,24 @@ export async function submitPay(
|
|||||||
throw Error("not submitting payment for aborted purchase");
|
throw Error("not submitting payment for aborted purchase");
|
||||||
}
|
}
|
||||||
const sessionId = purchase.lastSessionId;
|
const sessionId = purchase.lastSessionId;
|
||||||
let resp;
|
|
||||||
const payReq = { ...purchase.payReq, session_id: sessionId };
|
|
||||||
|
|
||||||
console.log("paying with session ID", sessionId);
|
console.log("paying with session ID", sessionId);
|
||||||
|
|
||||||
const payUrl = new URL("pay", purchase.contractData.merchantBaseUrl).href;
|
const payUrl = new URL(
|
||||||
|
`orders/${purchase.contractData.orderId}/pay`,
|
||||||
|
purchase.contractData.merchantBaseUrl,
|
||||||
|
).href;
|
||||||
|
|
||||||
|
const merchantResp = await httpPostTalerJson({
|
||||||
|
url: payUrl,
|
||||||
|
body: {
|
||||||
|
coins: purchase.coinDepositPermissions,
|
||||||
|
session_id: purchase.lastSessionId,
|
||||||
|
},
|
||||||
|
codec: codecForMerchantPayResponse(),
|
||||||
|
http: ws.http,
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
|
||||||
console.log("pay req", payReq);
|
|
||||||
resp = await ws.http.postJson(payUrl, payReq);
|
|
||||||
} catch (e) {
|
|
||||||
// Gives the user the option to retry / abort and refresh
|
|
||||||
console.log("payment failed", e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
if (resp.status !== 200) {
|
|
||||||
console.log(await resp.json());
|
|
||||||
throw Error(`unexpected status (${resp.status}) for /pay`);
|
|
||||||
}
|
|
||||||
const merchantResp = await resp.json();
|
|
||||||
console.log("got success from pay URL", merchantResp);
|
console.log("got success from pay URL", merchantResp);
|
||||||
|
|
||||||
const now = getTimestampNow();
|
const now = getTimestampNow();
|
||||||
@ -1030,7 +1022,7 @@ export async function confirmPay(
|
|||||||
coinPriv: coin.coinPriv,
|
coinPriv: coin.coinPriv,
|
||||||
coinPub: coin.coinPub,
|
coinPub: coin.coinPub,
|
||||||
contractTermsHash: d.contractData.contractTermsHash,
|
contractTermsHash: d.contractData.contractTermsHash,
|
||||||
denomPub: coin.denomPub,
|
denomPubHash: coin.denomPubHash,
|
||||||
denomSig: coin.denomSig,
|
denomSig: coin.denomSig,
|
||||||
exchangeBaseUrl: coin.exchangeBaseUrl,
|
exchangeBaseUrl: coin.exchangeBaseUrl,
|
||||||
feeDeposit: denom.feeDeposit,
|
feeDeposit: denom.feeDeposit,
|
||||||
@ -1050,8 +1042,6 @@ export async function confirmPay(
|
|||||||
sessionIdOverride,
|
sessionIdOverride,
|
||||||
);
|
);
|
||||||
|
|
||||||
logger.trace("confirmPay: submitting payment after creating purchase record");
|
|
||||||
logger.trace("purchaseRecord:", purchase);
|
|
||||||
return submitPay(ws, proposalId);
|
return submitPay(ws, proposalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1250,10 +1250,9 @@ export interface PurchaseRecord {
|
|||||||
contractData: WalletContractData;
|
contractData: WalletContractData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The payment request, ready to be send to the merchant's
|
* Deposit permissions, available once the user has accepted the payment.
|
||||||
* /pay URL.
|
|
||||||
*/
|
*/
|
||||||
payReq: PayReq;
|
coinDepositPermissions: CoinDepositPermission[];
|
||||||
|
|
||||||
payCoinSelection: PayCoinSelection;
|
payCoinSelection: PayCoinSelection;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ export interface CoinDepositPermission {
|
|||||||
/**
|
/**
|
||||||
* The denomination public key associated with this coin.
|
* The denomination public key associated with this coin.
|
||||||
*/
|
*/
|
||||||
denom_pub: string;
|
h_denom: string;
|
||||||
/**
|
/**
|
||||||
* The amount that is subtracted from this coin with this payment.
|
* The amount that is subtracted from this coin with this payment.
|
||||||
*/
|
*/
|
||||||
@ -433,31 +433,6 @@ export class ContractTerms {
|
|||||||
extra: any;
|
extra: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Payment body sent to the merchant's /pay.
|
|
||||||
*/
|
|
||||||
export interface PayReq {
|
|
||||||
/**
|
|
||||||
* Coins with signature.
|
|
||||||
*/
|
|
||||||
coins: CoinDepositPermission[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The merchant public key, used to uniquely
|
|
||||||
* identify the merchant instance.
|
|
||||||
*/
|
|
||||||
merchant_pub: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Order ID that's being payed for.
|
|
||||||
*/
|
|
||||||
order_id: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mode for /pay.
|
|
||||||
*/
|
|
||||||
mode: "pay" | "abort-refund";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refund permission in the format that the merchant gives it to us.
|
* Refund permission in the format that the merchant gives it to us.
|
||||||
@ -809,6 +784,10 @@ export interface CoinDumpJson {
|
|||||||
}>;
|
}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MerchantPayResponse {
|
||||||
|
sig: string;
|
||||||
|
}
|
||||||
|
|
||||||
export type AmountString = string;
|
export type AmountString = string;
|
||||||
export type Base32String = string;
|
export type Base32String = string;
|
||||||
export type EddsaSignatureString = string;
|
export type EddsaSignatureString = string;
|
||||||
@ -1044,3 +1023,8 @@ export const codecForWithdrawResponse = (): Codec<WithdrawResponse> =>
|
|||||||
makeCodecForObject<WithdrawResponse>()
|
makeCodecForObject<WithdrawResponse>()
|
||||||
.property("ev_sig", codecForString)
|
.property("ev_sig", codecForString)
|
||||||
.build("WithdrawResponse");
|
.build("WithdrawResponse");
|
||||||
|
|
||||||
|
export const codecForMerchantPayResponse = (): Codec<MerchantPayResponse> =>
|
||||||
|
makeCodecForObject<MerchantPayResponse>()
|
||||||
|
.property("sig", codecForString)
|
||||||
|
.build("MerchantPayResponse");
|
||||||
|
@ -473,7 +473,7 @@ export interface DepositInfo {
|
|||||||
merchantPub: string;
|
merchantPub: string;
|
||||||
feeDeposit: AmountJson;
|
feeDeposit: AmountJson;
|
||||||
wireInfoHash: string;
|
wireInfoHash: string;
|
||||||
denomPub: string;
|
denomPubHash: string;
|
||||||
denomSig: string;
|
denomSig: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user