@unchainedshop/plugins 3.1.10 → 4.0.0-rc.2
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/lib/delivery/pick-mup.js +0 -2
- package/lib/delivery/pick-mup.js.map +1 -1
- package/lib/files/gridfs/module.d.ts +2 -2
- package/lib/files/gridfs/module.d.ts.map +1 -1
- package/lib/filters/local-search.d.ts.map +1 -1
- package/lib/filters/local-search.js +9 -2
- package/lib/filters/local-search.js.map +1 -1
- package/lib/payment/apple-iap/adapter.js +5 -12
- package/lib/payment/apple-iap/adapter.js.map +1 -1
- package/lib/payment/apple-iap/fix-periods.d.ts.map +1 -1
- package/lib/payment/apple-iap/fix-periods.js +3 -5
- package/lib/payment/apple-iap/fix-periods.js.map +1 -1
- package/lib/payment/apple-iap/handler-express.js +3 -3
- package/lib/payment/apple-iap/handler-express.js.map +1 -1
- package/lib/payment/apple-iap/handler-fastify.js +3 -3
- package/lib/payment/apple-iap/handler-fastify.js.map +1 -1
- package/lib/payment/apple-iap/module.d.ts +2 -2
- package/lib/payment/apple-iap/module.d.ts.map +1 -1
- package/lib/payment/braintree.js +3 -4
- package/lib/payment/braintree.js.map +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts +1 -2
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts.map +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.js.map +1 -1
- package/lib/payment/cryptopay/de.d.ts +2 -0
- package/lib/payment/cryptopay/de.d.ts.map +1 -0
- package/lib/payment/cryptopay/de.js +10 -0
- package/lib/payment/cryptopay/de.js.map +1 -0
- package/lib/payment/cryptopay/denote-amount.d.ts +25 -0
- package/lib/payment/cryptopay/denote-amount.d.ts.map +1 -0
- package/lib/payment/cryptopay/denote-amount.js +31 -0
- package/lib/payment/cryptopay/denote-amount.js.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.d.ts +3 -0
- package/lib/payment/cryptopay/derive-btc-address.d.ts.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.js +39 -0
- package/lib/payment/cryptopay/derive-btc-address.js.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.d.ts +2 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.d.ts.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.js +10 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.js.map +1 -0
- package/lib/payment/cryptopay/derive-eth-address.d.ts +3 -0
- package/lib/payment/cryptopay/derive-eth-address.d.ts.map +1 -0
- package/lib/payment/cryptopay/derive-eth-address.js +32 -0
- package/lib/payment/cryptopay/derive-eth-address.js.map +1 -0
- package/lib/payment/cryptopay/handle-webhook.d.ts +26 -0
- package/lib/payment/cryptopay/handle-webhook.d.ts.map +1 -0
- package/lib/payment/cryptopay/handle-webhook.js +61 -0
- package/lib/payment/cryptopay/handle-webhook.js.map +1 -0
- package/lib/payment/cryptopay/handler-express.d.ts.map +1 -1
- package/lib/payment/cryptopay/handler-express.js +3 -56
- package/lib/payment/cryptopay/handler-express.js.map +1 -1
- package/lib/payment/cryptopay/handler-fastify.d.ts.map +1 -1
- package/lib/payment/cryptopay/handler-fastify.js +3 -55
- package/lib/payment/cryptopay/handler-fastify.js.map +1 -1
- package/lib/payment/cryptopay/module.d.ts +26 -26
- package/lib/payment/cryptopay/module.d.ts.map +1 -1
- package/lib/payment/cryptopay/module.js +26 -24
- package/lib/payment/cryptopay/module.js.map +1 -1
- package/lib/payment/cryptopay/plugin.d.ts.map +1 -1
- package/lib/payment/cryptopay/plugin.js +33 -79
- package/lib/payment/cryptopay/plugin.js.map +1 -1
- package/lib/payment/datatrans-v2/api/types.d.ts +41 -41
- package/lib/payment/datatrans-v2/api/types.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/getPaths.d.ts +2 -2
- package/lib/payment/datatrans-v2/getPaths.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/index.js +16 -14
- package/lib/payment/datatrans-v2/index.js.map +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.js +3 -3
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.js.map +1 -1
- package/lib/payment/paypal-checkout.js +1 -1
- package/lib/payment/paypal-checkout.js.map +1 -1
- package/lib/payment/payrexx/api/index.d.ts +2 -2
- package/lib/payment/payrexx/api/index.d.ts.map +1 -1
- package/lib/payment/payrexx/api/makeFetcher.d.ts.map +1 -1
- package/lib/payment/payrexx/api/makeFetcher.js.map +1 -1
- package/lib/payment/payrexx/index.js +4 -4
- package/lib/payment/payrexx/index.js.map +1 -1
- package/lib/payment/payrexx/payrexx.js +2 -2
- package/lib/payment/payrexx/payrexx.js.map +1 -1
- package/lib/payment/postfinance-checkout/index.js +3 -5
- package/lib/payment/postfinance-checkout/index.js.map +1 -1
- package/lib/payment/postfinance-checkout/types.d.ts +4 -4
- package/lib/payment/postfinance-checkout/types.d.ts.map +1 -1
- package/lib/payment/postfinance-checkout/utils.js +2 -2
- package/lib/payment/postfinance-checkout/utils.js.map +1 -1
- package/lib/payment/saferpay/adapter.d.ts.map +1 -1
- package/lib/payment/saferpay/adapter.js +4 -6
- package/lib/payment/saferpay/adapter.js.map +1 -1
- package/lib/payment/saferpay/api/models/Transaction.d.ts +2 -2
- package/lib/payment/saferpay/api/models/Transaction.d.ts.map +1 -1
- package/lib/payment/saferpay/module.d.ts +2 -2
- package/lib/payment/saferpay/module.d.ts.map +1 -1
- package/lib/payment/stripe/index.js +5 -5
- package/lib/payment/stripe/index.js.map +1 -1
- package/lib/payment/stripe/stripe.js +3 -3
- package/lib/payment/stripe/stripe.js.map +1 -1
- package/lib/presets/all.d.ts +12 -12
- package/lib/presets/all.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.js +2 -2
- package/lib/pricing/delivery-swiss-tax.js.map +1 -1
- package/lib/pricing/order-delivery.js +1 -1
- package/lib/pricing/order-delivery.js.map +1 -1
- package/lib/pricing/order-discount.js +3 -3
- package/lib/pricing/order-discount.js.map +1 -1
- package/lib/pricing/order-items-discount.js +1 -1
- package/lib/pricing/order-items-discount.js.map +1 -1
- package/lib/pricing/order-items.js +1 -1
- package/lib/pricing/order-items.js.map +1 -1
- package/lib/pricing/order-payment.js +1 -1
- package/lib/pricing/order-payment.js.map +1 -1
- package/lib/pricing/order-round.d.ts +1 -1
- package/lib/pricing/order-round.d.ts.map +1 -1
- package/lib/pricing/order-round.js +8 -8
- package/lib/pricing/order-round.js.map +1 -1
- package/lib/pricing/product-catalog-price.d.ts +0 -1
- package/lib/pricing/product-catalog-price.d.ts.map +1 -1
- package/lib/pricing/product-catalog-price.js +6 -18
- package/lib/pricing/product-catalog-price.js.map +1 -1
- package/lib/pricing/product-price-rateconversion.js +2 -2
- package/lib/pricing/product-price-rateconversion.js.map +1 -1
- package/lib/pricing/product-round.d.ts +1 -1
- package/lib/pricing/product-round.d.ts.map +1 -1
- package/lib/pricing/product-round.js +2 -2
- package/lib/pricing/product-round.js.map +1 -1
- package/lib/pricing/product-swiss-tax.d.ts +1 -1
- package/lib/pricing/product-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/product-swiss-tax.js +2 -2
- package/lib/pricing/product-swiss-tax.js.map +1 -1
- package/lib/warehousing/eth-minter.js +2 -2
- package/lib/warehousing/eth-minter.js.map +1 -1
- package/lib/worker/bulk-import.js +1 -1
- package/lib/worker/bulk-import.js.map +1 -1
- package/lib/worker/enrollment-order-generator.js +1 -1
- package/lib/worker/enrollment-order-generator.js.map +1 -1
- package/lib/worker/error-notifications.d.ts +4 -4
- package/lib/worker/error-notifications.d.ts.map +1 -1
- package/lib/worker/message.d.ts +1 -1
- package/lib/worker/message.d.ts.map +1 -1
- package/lib/worker/sms.js +16 -16
- package/lib/worker/sms.js.map +1 -1
- package/lib/worker/update-coinbase-rates.js +1 -1
- package/lib/worker/update-coinbase-rates.js.map +1 -1
- package/lib/worker/update-ecb-rates.js.map +1 -1
- package/package.json +37 -53
- package/src/delivery/pick-mup.ts +0 -2
- package/src/files/gridfs/module.ts +2 -2
- package/src/filters/local-search.ts +11 -2
- package/src/payment/apple-iap/adapter.ts +6 -13
- package/src/payment/apple-iap/fix-periods.ts +4 -7
- package/src/payment/apple-iap/handler-express.ts +3 -3
- package/src/payment/apple-iap/handler-fastify.ts +3 -3
- package/src/payment/apple-iap/module.ts +2 -2
- package/src/payment/braintree.ts +3 -4
- package/src/payment/cryptopay/db/CryptopayTransactions.ts +1 -2
- package/src/payment/cryptopay/denote-amount.test.ts +28 -0
- package/src/payment/cryptopay/denote-amount.ts +29 -0
- package/src/payment/cryptopay/derive-btc-address.test.ts +22 -0
- package/src/payment/cryptopay/derive-btc-address.ts +48 -0
- package/src/payment/cryptopay/derive-eth-address.test.ts +22 -0
- package/src/payment/cryptopay/derive-eth-address.ts +38 -0
- package/src/payment/cryptopay/handle-webhook.ts +103 -0
- package/src/payment/cryptopay/handler-express.ts +3 -69
- package/src/payment/cryptopay/handler-fastify.ts +5 -70
- package/src/payment/cryptopay/module.ts +44 -40
- package/src/payment/cryptopay/plugin.ts +50 -87
- package/src/payment/cryptopay/readme.md +23 -1
- package/src/payment/datatrans-v2/api/types.ts +41 -41
- package/src/payment/datatrans-v2/getPaths.ts +2 -2
- package/src/payment/datatrans-v2/index.ts +17 -15
- package/src/payment/datatrans-v2/roundedAmountFromOrder.ts +4 -4
- package/src/payment/paypal-checkout.ts +1 -1
- package/src/payment/payrexx/api/index.ts +2 -2
- package/src/payment/payrexx/api/makeFetcher.ts +1 -1
- package/src/payment/payrexx/index.ts +4 -4
- package/src/payment/payrexx/payrexx.ts +2 -2
- package/src/payment/postfinance-checkout/index.ts +3 -5
- package/src/payment/postfinance-checkout/types.ts +6 -6
- package/src/payment/postfinance-checkout/utils.ts +2 -2
- package/src/payment/saferpay/adapter.ts +4 -6
- package/src/payment/saferpay/api/models/Transaction.ts +2 -2
- package/src/payment/saferpay/module.ts +2 -2
- package/src/payment/stripe/index.ts +5 -5
- package/src/payment/stripe/stripe.ts +3 -3
- package/src/pricing/delivery-swiss-tax.ts +6 -2
- package/src/pricing/order-delivery.ts +1 -1
- package/src/pricing/order-discount.ts +3 -3
- package/src/pricing/order-items-discount.ts +1 -1
- package/src/pricing/order-items.ts +1 -1
- package/src/pricing/order-payment.ts +1 -1
- package/src/pricing/order-round.ts +9 -9
- package/src/pricing/product-catalog-price.ts +6 -25
- package/src/pricing/product-price-rateconversion.ts +2 -2
- package/src/pricing/product-round.ts +3 -3
- package/src/pricing/product-swiss-tax.test.ts +6 -6
- package/src/pricing/product-swiss-tax.ts +2 -2
- package/src/warehousing/eth-minter.ts +2 -2
- package/src/worker/bulk-import.ts +1 -1
- package/src/worker/enrollment-order-generator.ts +3 -3
- package/src/worker/error-notifications.ts +4 -4
- package/src/worker/heartbeat.ts +2 -2
- package/src/worker/message.ts +1 -1
- package/src/worker/push-notification.ts +2 -2
- package/src/worker/sms.ts +19 -17
- package/src/worker/update-coinbase-rates.ts +3 -6
- package/src/worker/update-ecb-rates.ts +3 -3
- package/src/worker/BaseWorker.ts +0 -116
- package/src/worker/EventListenerWorker.ts +0 -61
- package/src/worker/FailedRescheduler.ts +0 -80
- package/src/worker/IntervalWorker.ts +0 -54
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
import { ethers } from 'ethers';
|
|
2
|
-
import { BIP32Factory } from 'bip32';
|
|
3
|
-
import bs58check from 'bs58check';
|
|
4
|
-
import * as ecc from 'tiny-secp256k1';
|
|
5
|
-
import { networks, payments } from 'bitcoinjs-lib';
|
|
6
|
-
import { createLogger } from '@unchainedshop/logger';
|
|
7
1
|
import {
|
|
8
2
|
IPaymentAdapter,
|
|
9
3
|
PaymentAdapter,
|
|
@@ -11,52 +5,28 @@ import {
|
|
|
11
5
|
PaymentError,
|
|
12
6
|
OrderPricingSheet,
|
|
13
7
|
} from '@unchainedshop/core';
|
|
8
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
9
|
+
|
|
14
10
|
import { CryptopayModule } from './module.js';
|
|
11
|
+
import deriveBtcAddress from './derive-btc-address.js';
|
|
12
|
+
import deriveEthAddress from './derive-eth-address.js';
|
|
13
|
+
import denoteAmount from './denote-amount.js';
|
|
15
14
|
|
|
16
15
|
const logger = createLogger('unchained:core-payment:cryptopay');
|
|
17
16
|
|
|
18
17
|
const { CRYPTOPAY_SECRET, CRYPTOPAY_BTC_XPUB, CRYPTOPAY_ETH_XPUB } = process.env;
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
if (prefix === 'x') return `m/44'/0'`;
|
|
22
|
-
if (prefix === 'y') return `m/49'/0'`;
|
|
23
|
-
if (prefix === 'z') return `m/84'/0'`;
|
|
24
|
-
if (prefix === 't') return `m/44'/1'`;
|
|
25
|
-
if (prefix === 'u') return `m/49'/1'`;
|
|
26
|
-
if (prefix === 'v') return `m/84'/1'`;
|
|
27
|
-
return `m`;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const resolveNetwork = (prefix) => {
|
|
31
|
-
if (['x', 'y', 'z'].includes(prefix)) return networks.bitcoin;
|
|
32
|
-
return networks.testnet;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
function convertExtendedPublicKey(z) {
|
|
36
|
-
const derivationPath = resolvePath(z.slice(0, 1));
|
|
37
|
-
const network = resolveNetwork(z.slice(0, 1));
|
|
38
|
-
// https://github.com/satoshilabs/slips/blob/master/slip-0132.md
|
|
39
|
-
let data = bs58check.decode(z);
|
|
40
|
-
data = data.slice(4);
|
|
41
|
-
data = Buffer.concat([Buffer.from('0488b21e', 'hex'), data]);
|
|
42
|
-
return {
|
|
43
|
-
xpub: bs58check.encode(data),
|
|
44
|
-
network,
|
|
45
|
-
derivationPath,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
enum CryptopayCurrencies { // eslint-disable-line
|
|
19
|
+
enum CryptopayCurrencies {
|
|
50
20
|
BTC = 'BTC',
|
|
51
21
|
ETH = 'ETH',
|
|
52
22
|
}
|
|
53
23
|
|
|
54
|
-
|
|
55
|
-
|
|
24
|
+
interface CryptopayAddress {
|
|
25
|
+
currencyCode: CryptopayCurrencies;
|
|
56
26
|
address: string;
|
|
57
27
|
currencyConversionRate?: number;
|
|
58
28
|
currencyConversionExpiryDate?: Date;
|
|
59
|
-
}
|
|
29
|
+
}
|
|
60
30
|
|
|
61
31
|
const Cryptopay: IPaymentAdapter = {
|
|
62
32
|
...PaymentAdapter,
|
|
@@ -77,7 +47,7 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
77
47
|
const updatedAddresses = await Promise.all(
|
|
78
48
|
existingAddresses.map(async (addressData) => {
|
|
79
49
|
const targetCurrencyObj = await modules.currencies.findCurrency({
|
|
80
|
-
isoCode: addressData.
|
|
50
|
+
isoCode: addressData.currencyCode,
|
|
81
51
|
});
|
|
82
52
|
if (!targetCurrencyObj?.isActive) return null;
|
|
83
53
|
const rateData = await modules.products.prices.rates.getRate(
|
|
@@ -98,24 +68,20 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
98
68
|
orderPaymentId: string,
|
|
99
69
|
cryptoAddresses: CryptopayAddress[],
|
|
100
70
|
) => {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
),
|
|
110
|
-
);
|
|
71
|
+
for (const cryptoAddress of cryptoAddresses) {
|
|
72
|
+
const { address, currencyCode } = cryptoAddress;
|
|
73
|
+
await modules.cryptopay.mapOrderPaymentToWalletAddress({
|
|
74
|
+
address,
|
|
75
|
+
currencyCode,
|
|
76
|
+
orderPaymentId,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
111
79
|
};
|
|
112
80
|
|
|
113
81
|
const adapterActions = {
|
|
114
82
|
...PaymentAdapter.actions(config, context),
|
|
115
83
|
|
|
116
|
-
// eslint-disable-next-line
|
|
117
84
|
configurationError() {
|
|
118
|
-
// eslint-disable-line
|
|
119
85
|
if (!CRYPTOPAY_SECRET) {
|
|
120
86
|
return PaymentError.INCOMPLETE_CONFIGURATION;
|
|
121
87
|
}
|
|
@@ -131,7 +97,7 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
131
97
|
if (!context.order) return true;
|
|
132
98
|
// if (
|
|
133
99
|
// !Object.values(CryptopayCurrencies).includes(
|
|
134
|
-
// context.order.
|
|
100
|
+
// context.order.currencyCode as CryptopayCurrencies,
|
|
135
101
|
// )
|
|
136
102
|
// )
|
|
137
103
|
// return false;
|
|
@@ -144,6 +110,8 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
144
110
|
|
|
145
111
|
sign: async () => {
|
|
146
112
|
const { orderPayment, order } = context;
|
|
113
|
+
if (!orderPayment)
|
|
114
|
+
throw new Error('Payment Credential Registration is not yet supported for Cryptopay');
|
|
147
115
|
|
|
148
116
|
const existingAddresses = await modules.cryptopay.getWalletAddressesByOrderPaymentId(
|
|
149
117
|
orderPayment._id,
|
|
@@ -151,12 +119,12 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
151
119
|
if (existingAddresses.length) {
|
|
152
120
|
// Do not derive addresses a second time for order payment, return existing addresses
|
|
153
121
|
const existingAddressesWithNewExpiration = await setConversionRates(
|
|
154
|
-
order.
|
|
122
|
+
order.currencyCode,
|
|
155
123
|
existingAddresses.map(
|
|
156
|
-
({ _id,
|
|
124
|
+
({ _id, currencyCode }) =>
|
|
157
125
|
({
|
|
158
126
|
address: _id,
|
|
159
|
-
|
|
127
|
+
currencyCode,
|
|
160
128
|
}) as CryptopayAddress,
|
|
161
129
|
),
|
|
162
130
|
);
|
|
@@ -165,37 +133,32 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
165
133
|
|
|
166
134
|
const cryptoAddresses: CryptopayAddress[] = [];
|
|
167
135
|
if (CRYPTOPAY_BTC_XPUB) {
|
|
168
|
-
const { xpub, network } = convertExtendedPublicKey(CRYPTOPAY_BTC_XPUB);
|
|
169
|
-
const bip32 = BIP32Factory(ecc);
|
|
170
|
-
const hardenedMaster = bip32.fromBase58(xpub, network);
|
|
171
136
|
const btcDerivationNumber = await modules.cryptopay.getNextDerivationNumber(
|
|
172
137
|
CryptopayCurrencies.BTC,
|
|
173
138
|
);
|
|
174
|
-
|
|
139
|
+
|
|
140
|
+
const address = deriveBtcAddress(CRYPTOPAY_BTC_XPUB, btcDerivationNumber);
|
|
175
141
|
cryptoAddresses.push({
|
|
176
|
-
|
|
177
|
-
address
|
|
178
|
-
pubkey: child.publicKey as Buffer,
|
|
179
|
-
network,
|
|
180
|
-
}).address,
|
|
142
|
+
currencyCode: CryptopayCurrencies.BTC,
|
|
143
|
+
address,
|
|
181
144
|
});
|
|
182
145
|
}
|
|
183
146
|
if (CRYPTOPAY_ETH_XPUB) {
|
|
184
|
-
// we neuter for security reasons, it's still quite complicated for most ethereum clients to show an appropriate
|
|
185
|
-
// xpub, that's why
|
|
186
|
-
const hdWallet = ethers.HDNodeWallet.fromExtendedKey(CRYPTOPAY_ETH_XPUB);
|
|
187
|
-
const hardenedMaster = 'neuter' in hdWallet ? hdWallet.neuter() : hdWallet;
|
|
188
|
-
|
|
189
147
|
const ethDerivationNumber = await modules.cryptopay.getNextDerivationNumber(
|
|
190
148
|
CryptopayCurrencies.ETH,
|
|
191
149
|
);
|
|
150
|
+
|
|
151
|
+
const address = deriveEthAddress(CRYPTOPAY_ETH_XPUB, ethDerivationNumber);
|
|
192
152
|
cryptoAddresses.push({
|
|
193
|
-
|
|
194
|
-
address
|
|
153
|
+
currencyCode: CryptopayCurrencies.ETH,
|
|
154
|
+
address,
|
|
195
155
|
});
|
|
196
156
|
}
|
|
197
157
|
|
|
198
|
-
const cryptoAddressesWithExpiration = await setConversionRates(
|
|
158
|
+
const cryptoAddressesWithExpiration = await setConversionRates(
|
|
159
|
+
order.currencyCode,
|
|
160
|
+
cryptoAddresses,
|
|
161
|
+
);
|
|
199
162
|
await updateTransactionsWithOrderPaymentId(orderPayment._id, cryptoAddresses);
|
|
200
163
|
return JSON.stringify(cryptoAddressesWithExpiration);
|
|
201
164
|
},
|
|
@@ -213,15 +176,15 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
213
176
|
|
|
214
177
|
const pricing = OrderPricingSheet({
|
|
215
178
|
calculation: order.calculation,
|
|
216
|
-
|
|
179
|
+
currencyCode: order.currencyCode,
|
|
217
180
|
});
|
|
218
181
|
const totalAmount = BigInt(pricing?.total({ useNetPrice: false }).amount);
|
|
219
182
|
|
|
220
|
-
if (walletForOrderPayment.
|
|
183
|
+
if (walletForOrderPayment.currencyCode !== order.currencyCode) {
|
|
221
184
|
const baseCurrency = await modules.currencies.findCurrency({
|
|
222
|
-
isoCode: walletForOrderPayment.
|
|
185
|
+
isoCode: walletForOrderPayment.currencyCode,
|
|
223
186
|
});
|
|
224
|
-
const quoteCurrency = await modules.currencies.findCurrency({ isoCode: order.
|
|
187
|
+
const quoteCurrency = await modules.currencies.findCurrency({ isoCode: order.currencyCode });
|
|
225
188
|
|
|
226
189
|
const { /* min, */ max } = await modules.products.prices.rates.getRateRange(
|
|
227
190
|
baseCurrency,
|
|
@@ -229,9 +192,10 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
229
192
|
order.confirmed || new Date(),
|
|
230
193
|
);
|
|
231
194
|
|
|
232
|
-
const convertedAmount =
|
|
233
|
-
|
|
234
|
-
|
|
195
|
+
const convertedAmount = denoteAmount(
|
|
196
|
+
walletForOrderPayment.amount.toString(),
|
|
197
|
+
walletForOrderPayment.decimals,
|
|
198
|
+
);
|
|
235
199
|
|
|
236
200
|
// Add a Promille 🍻
|
|
237
201
|
// const minAmount = parseFloat(convertedAmount.toString()) * min * 0.999;
|
|
@@ -249,10 +213,10 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
249
213
|
}
|
|
250
214
|
|
|
251
215
|
if (walletForOrderPayment) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
216
|
+
const convertedAmount = denoteAmount(
|
|
217
|
+
walletForOrderPayment.amount.toString(),
|
|
218
|
+
walletForOrderPayment.decimals,
|
|
219
|
+
);
|
|
256
220
|
|
|
257
221
|
if (convertedAmount && convertedAmount >= totalAmount) {
|
|
258
222
|
return {
|
|
@@ -266,12 +230,11 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
266
230
|
|
|
267
231
|
logger.info(
|
|
268
232
|
`Cryptopay Plugin: No confirmed payments found for currency ${
|
|
269
|
-
order.
|
|
233
|
+
order.currencyCode
|
|
270
234
|
} and addresses ${JSON.stringify(foundWalletsWithBalances)}`,
|
|
271
235
|
);
|
|
272
236
|
|
|
273
|
-
/*
|
|
274
|
-
TODO:
|
|
237
|
+
/* TODO: Crypto Handling
|
|
275
238
|
|
|
276
239
|
1. Check that generated crypto addresses are unique and no order payments share the same crypto address, only repeat when derivations completely exhausted.
|
|
277
240
|
2. When derivation path get's close to "exhaustedness" (95%), send a special e-mail alert to tell the user should generate a new xpub.
|
|
@@ -1 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
# Cryptopay
|
|
2
|
+
|
|
3
|
+
curl -X POST http://localhost:4010/payment/cryptopay -d '{ "secret": "secret", "address": "0xF5F72AE7fa1fa990ebaF163208Ed7aD6a3f42DEA", "blockHeight": 7469853, "amount": "50000000000000000", "decimals": 18, "currency": "ETH"}' -H 'Content-Type: application/json'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
## HD Key Requirements
|
|
7
|
+
|
|
8
|
+
Using HD keys allows us to generate "child-keys" for every payment. This helps us link payments to checkouts and improves privacy of the vendor as we don't expose the grand total of revenue the vendor makes on the blockchain directly.
|
|
9
|
+
|
|
10
|
+
**Bitcoin:**
|
|
11
|
+
For the extended HD key we only support native segwit (zpub) format, so if you have a ypub for example, use this tool here to make it the correct format:
|
|
12
|
+
|
|
13
|
+
https://3rditeration.github.io/btc-extended-key-converter/
|
|
14
|
+
|
|
15
|
+
**Ethereum:**
|
|
16
|
+
For the extended HD key we need an extended public key using the discussed derivation path here:
|
|
17
|
+
https://github.com/ethereum/EIPs/issues/84
|
|
18
|
+
https://github.com/satoshilabs/slips/blob/master/slip-0044.md
|
|
19
|
+
|
|
20
|
+
Thus, we are deriving child keys the Metamask way:
|
|
21
|
+
m/44'/60'/0'/0/0
|
|
22
|
+
m/44'/60'/0'/0/1
|
|
23
|
+
m/44'/60'/0'/0/...
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface Address {
|
|
2
2
|
gender?: 'female' | 'male';
|
|
3
3
|
title?: string;
|
|
4
4
|
name?: string;
|
|
@@ -9,8 +9,8 @@ export type Address = {
|
|
|
9
9
|
street2?: string;
|
|
10
10
|
zipCode?: string;
|
|
11
11
|
city?: string;
|
|
12
|
-
|
|
13
|
-
}
|
|
12
|
+
countryCode?: string;
|
|
13
|
+
}
|
|
14
14
|
|
|
15
15
|
export type BillingAddress = Address & {
|
|
16
16
|
countrySubdivision?: string;
|
|
@@ -40,14 +40,14 @@ export type Customer = Address & {
|
|
|
40
40
|
ipAddress?: string;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
export
|
|
43
|
+
export interface Order {
|
|
44
44
|
articles: Record<string, unknown>;
|
|
45
45
|
taxAmount: number;
|
|
46
46
|
shippingAmount: number;
|
|
47
47
|
discountAmount: number;
|
|
48
|
-
}
|
|
48
|
+
}
|
|
49
49
|
|
|
50
|
-
export
|
|
50
|
+
export interface DT2015Configuration {
|
|
51
51
|
brandColor: string;
|
|
52
52
|
textColor: 'white' | 'black';
|
|
53
53
|
logoType: 'circle' | 'rectangle' | 'none';
|
|
@@ -57,7 +57,7 @@ export type DT2015Configuration = {
|
|
|
57
57
|
logoSrc: string;
|
|
58
58
|
initialView: 'list' | 'grid';
|
|
59
59
|
brandTitle: string;
|
|
60
|
-
}
|
|
60
|
+
}
|
|
61
61
|
|
|
62
62
|
export type SupportedLanguage =
|
|
63
63
|
| 'de'
|
|
@@ -129,7 +129,7 @@ export type TransactionStatusCode =
|
|
|
129
129
|
| 'transmitted'
|
|
130
130
|
| 'failed';
|
|
131
131
|
|
|
132
|
-
export
|
|
132
|
+
export interface ResponseError {
|
|
133
133
|
error: {
|
|
134
134
|
code:
|
|
135
135
|
| 'UNKNOWN_ERROR'
|
|
@@ -157,19 +157,19 @@ export type ResponseError = {
|
|
|
157
157
|
| 'INVALID_SETUP';
|
|
158
158
|
message: string;
|
|
159
159
|
};
|
|
160
|
-
}
|
|
160
|
+
}
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
interface Split {
|
|
163
163
|
subMerchantId: string;
|
|
164
164
|
amount: number;
|
|
165
165
|
commission: number;
|
|
166
|
-
}
|
|
166
|
+
}
|
|
167
167
|
|
|
168
|
-
export
|
|
168
|
+
export interface Marketplace {
|
|
169
169
|
splits: Split[];
|
|
170
|
-
}
|
|
170
|
+
}
|
|
171
171
|
|
|
172
|
-
export
|
|
172
|
+
export interface InitRequestPayload {
|
|
173
173
|
endpoint: string;
|
|
174
174
|
secret: string;
|
|
175
175
|
merchantId: string;
|
|
@@ -222,21 +222,21 @@ export type InitRequestPayload = {
|
|
|
222
222
|
rememberMe?: 'true' | 'checked';
|
|
223
223
|
returnMobileToken?: boolean;
|
|
224
224
|
};
|
|
225
|
-
}
|
|
225
|
+
}
|
|
226
226
|
|
|
227
|
-
export
|
|
227
|
+
export interface InitResponseSuccess {
|
|
228
228
|
transactionId: string;
|
|
229
229
|
mobileToken?: string;
|
|
230
230
|
WEC?: Record<string, unknown>;
|
|
231
231
|
['3D']?: Record<string, unknown>;
|
|
232
232
|
location?: string;
|
|
233
|
-
}
|
|
233
|
+
}
|
|
234
234
|
|
|
235
|
-
export
|
|
235
|
+
export interface StatusRequestPayload {
|
|
236
236
|
transactionId: string;
|
|
237
|
-
}
|
|
237
|
+
}
|
|
238
238
|
|
|
239
|
-
export
|
|
239
|
+
export interface StatusResponseSuccess {
|
|
240
240
|
transactionId: string;
|
|
241
241
|
type: TransactionType;
|
|
242
242
|
status: TransactionStatusCode;
|
|
@@ -265,20 +265,20 @@ export type StatusResponseSuccess = {
|
|
|
265
265
|
SCX?: Record<string, unknown>;
|
|
266
266
|
history: Record<string, unknown>[];
|
|
267
267
|
ep2?: Record<string, unknown>;
|
|
268
|
-
}
|
|
268
|
+
}
|
|
269
269
|
|
|
270
|
-
export
|
|
270
|
+
export interface SecureFieldsRequestPayload {
|
|
271
271
|
currency: string;
|
|
272
272
|
returnUrl?: string;
|
|
273
273
|
amount?: number;
|
|
274
274
|
['3D']?: Record<string, unknown>;
|
|
275
|
-
}
|
|
275
|
+
}
|
|
276
276
|
|
|
277
|
-
export
|
|
277
|
+
export interface SecureFieldsResponseSuccess {
|
|
278
278
|
transactionId: string;
|
|
279
|
-
}
|
|
279
|
+
}
|
|
280
280
|
|
|
281
|
-
export
|
|
281
|
+
export interface AuthorizeRequestPayload {
|
|
282
282
|
amount: number;
|
|
283
283
|
currency: string;
|
|
284
284
|
refno: string;
|
|
@@ -303,14 +303,14 @@ export type AuthorizeRequestPayload = {
|
|
|
303
303
|
SWB?: Record<string, unknown>;
|
|
304
304
|
airlineData?: Record<string, unknown>;
|
|
305
305
|
marketplace?: Marketplace;
|
|
306
|
-
}
|
|
306
|
+
}
|
|
307
307
|
|
|
308
|
-
export
|
|
308
|
+
export interface AuthorizeResponseSuccess {
|
|
309
309
|
transactionId: string;
|
|
310
310
|
acquirerAuthorizationCode?: string;
|
|
311
|
-
}
|
|
311
|
+
}
|
|
312
312
|
|
|
313
|
-
export
|
|
313
|
+
export interface AuthorizeAuthenticatedRequestPayload {
|
|
314
314
|
transactionId: string;
|
|
315
315
|
refno: string;
|
|
316
316
|
amount?: number;
|
|
@@ -319,13 +319,13 @@ export type AuthorizeAuthenticatedRequestPayload = {
|
|
|
319
319
|
autoSettle?: boolean;
|
|
320
320
|
CDM?: Record<string, unknown>;
|
|
321
321
|
['3D']?: Record<string, unknown>;
|
|
322
|
-
}
|
|
322
|
+
}
|
|
323
323
|
|
|
324
|
-
export
|
|
324
|
+
export interface AuthorizeAuthenticatedResponseSuccess {
|
|
325
325
|
acquirerAuthorizationCode: string;
|
|
326
|
-
}
|
|
326
|
+
}
|
|
327
327
|
|
|
328
|
-
export
|
|
328
|
+
export interface ValidateRequestPayload {
|
|
329
329
|
currency: string;
|
|
330
330
|
refno: string;
|
|
331
331
|
refno2?: string;
|
|
@@ -336,14 +336,14 @@ export type ValidateRequestPayload = {
|
|
|
336
336
|
PAY?: Record<string, unknown>;
|
|
337
337
|
APL?: Record<string, unknown>;
|
|
338
338
|
ESY?: Record<string, unknown>;
|
|
339
|
-
}
|
|
339
|
+
}
|
|
340
340
|
|
|
341
|
-
export
|
|
341
|
+
export interface ValidateResponseSuccess {
|
|
342
342
|
transactionId: string;
|
|
343
343
|
acquirerAuthorizationCode?: string;
|
|
344
|
-
}
|
|
344
|
+
}
|
|
345
345
|
|
|
346
|
-
export
|
|
346
|
+
export interface SettleRequestPayload {
|
|
347
347
|
transactionId: string;
|
|
348
348
|
amount: number;
|
|
349
349
|
currency: string;
|
|
@@ -352,12 +352,12 @@ export type SettleRequestPayload = {
|
|
|
352
352
|
airlineData?: Record<string, unknown>;
|
|
353
353
|
marketplace?: Marketplace;
|
|
354
354
|
extensions?: Record<string, string>;
|
|
355
|
-
}
|
|
355
|
+
}
|
|
356
356
|
|
|
357
|
-
export
|
|
357
|
+
export interface CancelRequestPayload {
|
|
358
358
|
transactionId: string;
|
|
359
359
|
refno: string;
|
|
360
|
-
}
|
|
360
|
+
}
|
|
361
361
|
|
|
362
362
|
export type InitResponse = InitResponseSuccess | ResponseError;
|
|
363
363
|
|
|
@@ -8,13 +8,13 @@ const {
|
|
|
8
8
|
DATATRANS_RETURN_PATH = '/datatrans/return',
|
|
9
9
|
} = process.env;
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
interface Paths {
|
|
12
12
|
postUrl: string;
|
|
13
13
|
cancelUrl: string;
|
|
14
14
|
successUrl: string;
|
|
15
15
|
errorUrl: string;
|
|
16
16
|
returnUrl: string;
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
18
|
|
|
19
19
|
export default (): Paths => ({
|
|
20
20
|
postUrl: `${ROOT_URL}${DATATRANS_WEBHOOK_PATH}`,
|
|
@@ -89,11 +89,11 @@ const Datatrans: IPaymentAdapter = {
|
|
|
89
89
|
|
|
90
90
|
const pricingForOrderPayment = PaymentPricingSheet({
|
|
91
91
|
calculation: orderPayment.calculation,
|
|
92
|
-
|
|
92
|
+
currencyCode: order.currencyCode,
|
|
93
93
|
});
|
|
94
94
|
const pricing = OrderPricingSheet({
|
|
95
95
|
calculation: order.calculation,
|
|
96
|
-
|
|
96
|
+
currencyCode: order.currencyCode,
|
|
97
97
|
});
|
|
98
98
|
|
|
99
99
|
const { amount: total } = pricing.total({ useNetPrice: false });
|
|
@@ -128,12 +128,12 @@ const Datatrans: IPaymentAdapter = {
|
|
|
128
128
|
const refno = Buffer.from(orderPayment._id, 'hex').toString('base64');
|
|
129
129
|
const userId = order?.userId || context?.userId;
|
|
130
130
|
const refno2 = userId;
|
|
131
|
-
const {
|
|
131
|
+
const { currencyCode, amount } = roundedAmountFromOrder(order);
|
|
132
132
|
const splits = await getMarketplaceSplits();
|
|
133
133
|
const result = await api().authorize({
|
|
134
134
|
...arbitraryFields,
|
|
135
135
|
amount,
|
|
136
|
-
currency,
|
|
136
|
+
currency: currencyCode,
|
|
137
137
|
refno,
|
|
138
138
|
refno2,
|
|
139
139
|
autoSettle: false,
|
|
@@ -158,12 +158,12 @@ const Datatrans: IPaymentAdapter = {
|
|
|
158
158
|
...arbitraryFields
|
|
159
159
|
}): Promise<string> => {
|
|
160
160
|
const { order } = context;
|
|
161
|
-
const {
|
|
161
|
+
const { currencyCode, amount } = roundedAmountFromOrder(order);
|
|
162
162
|
const result = await api().authorizeAuthenticated({
|
|
163
163
|
...arbitraryFields,
|
|
164
164
|
transactionId,
|
|
165
165
|
amount,
|
|
166
|
-
currency,
|
|
166
|
+
currency: currencyCode,
|
|
167
167
|
refno,
|
|
168
168
|
refno2,
|
|
169
169
|
autoSettle: false,
|
|
@@ -174,14 +174,14 @@ const Datatrans: IPaymentAdapter = {
|
|
|
174
174
|
|
|
175
175
|
const isTransactionAmountValid = (transaction: StatusResponseSuccess): boolean => {
|
|
176
176
|
const { order } = context;
|
|
177
|
-
const {
|
|
177
|
+
const { currencyCode, amount } = roundedAmountFromOrder(order);
|
|
178
178
|
if (
|
|
179
|
-
transaction.currency !==
|
|
179
|
+
transaction.currency !== currencyCode ||
|
|
180
180
|
(transaction.detail.authorize as any)?.amount !== amount
|
|
181
181
|
) {
|
|
182
182
|
logger.info(
|
|
183
|
-
`currency: ${transaction.currency} === ${
|
|
184
|
-
transaction.currency ===
|
|
183
|
+
`currency: ${transaction.currency} === ${currencyCode} => ${
|
|
184
|
+
transaction.currency === currencyCode
|
|
185
185
|
}, amount: ${(transaction.detail.authorize as any)?.amount} === ${amount} => ${
|
|
186
186
|
(transaction.detail.authorize as any)?.amount === amount
|
|
187
187
|
}`,
|
|
@@ -208,14 +208,14 @@ const Datatrans: IPaymentAdapter = {
|
|
|
208
208
|
|
|
209
209
|
const settle = async ({ transactionId, refno, refno2, extensions }): Promise<boolean> => {
|
|
210
210
|
const { order } = context;
|
|
211
|
-
const {
|
|
211
|
+
const { currencyCode, amount } = roundedAmountFromOrder(order);
|
|
212
212
|
const splits = await getMarketplaceSplits();
|
|
213
213
|
const result = await api().settle({
|
|
214
214
|
transactionId,
|
|
215
215
|
amount,
|
|
216
216
|
refno,
|
|
217
217
|
refno2,
|
|
218
|
-
currency,
|
|
218
|
+
currency: currencyCode,
|
|
219
219
|
marketplace: splits.length
|
|
220
220
|
? {
|
|
221
221
|
splits,
|
|
@@ -263,12 +263,14 @@ const Datatrans: IPaymentAdapter = {
|
|
|
263
263
|
);
|
|
264
264
|
const userId = order?.userId || context?.userId;
|
|
265
265
|
const refno2 = userId;
|
|
266
|
-
const price: { amount?: number;
|
|
266
|
+
const price: { amount?: number; currencyCode?: string } = order
|
|
267
|
+
? roundedAmountFromOrder(order)
|
|
268
|
+
: {};
|
|
267
269
|
|
|
268
270
|
if (useSecureFields) {
|
|
269
271
|
const result = await api().secureFields({
|
|
270
272
|
...arbitraryFields,
|
|
271
|
-
currency: price.
|
|
273
|
+
currency: price.currencyCode || 'CHF',
|
|
272
274
|
refno,
|
|
273
275
|
refno2,
|
|
274
276
|
customer: {
|
|
@@ -281,7 +283,7 @@ const Datatrans: IPaymentAdapter = {
|
|
|
281
283
|
}
|
|
282
284
|
const result = await api().init({
|
|
283
285
|
...arbitraryFields,
|
|
284
|
-
currency: price.
|
|
286
|
+
currency: price.currencyCode || 'CHF',
|
|
285
287
|
refno,
|
|
286
288
|
refno2,
|
|
287
289
|
customer: {
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { OrderPricingSheet } from '@unchainedshop/core';
|
|
2
2
|
import { Order } from '@unchainedshop/core-orders';
|
|
3
3
|
|
|
4
|
-
const roundedAmountFromOrder = (order: Order): {
|
|
4
|
+
const roundedAmountFromOrder = (order: Order): { currencyCode: string; amount: number } => {
|
|
5
5
|
const pricing = OrderPricingSheet({
|
|
6
6
|
calculation: order.calculation,
|
|
7
|
-
|
|
7
|
+
currencyCode: order.currencyCode,
|
|
8
8
|
});
|
|
9
|
-
const {
|
|
9
|
+
const { currencyCode, amount } = pricing.total({ useNetPrice: false });
|
|
10
10
|
return {
|
|
11
|
-
|
|
11
|
+
currencyCode,
|
|
12
12
|
amount: Math.round(amount),
|
|
13
13
|
};
|
|
14
14
|
};
|
|
@@ -90,7 +90,7 @@ const PaypalCheckout: IPaymentAdapter = {
|
|
|
90
90
|
|
|
91
91
|
const pricing = OrderPricingSheet({
|
|
92
92
|
calculation: order.calculation,
|
|
93
|
-
|
|
93
|
+
currencyCode: order.currencyCode,
|
|
94
94
|
});
|
|
95
95
|
const ourTotal = (pricing.total({ useNetPrice: false }).amount / 100).toFixed(2);
|
|
96
96
|
const paypalTotal = paypalOrder.result.purchase_units[0].amount.value;
|
|
@@ -17,7 +17,7 @@ export enum GatewayObjectStatus {
|
|
|
17
17
|
uncaptured = '_',
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export
|
|
20
|
+
export interface GatewayObject {
|
|
21
21
|
status: GatewayObjectStatus;
|
|
22
22
|
currency: string;
|
|
23
23
|
amount: number;
|
|
@@ -27,7 +27,7 @@ export type GatewayObject = {
|
|
|
27
27
|
id: string;
|
|
28
28
|
}[];
|
|
29
29
|
}[];
|
|
30
|
-
}
|
|
30
|
+
}
|
|
31
31
|
|
|
32
32
|
export type TransactionObject = any;
|
|
33
33
|
|
|
@@ -5,7 +5,7 @@ const { MOCK_APIS } = process.env;
|
|
|
5
5
|
const logger = createLogger('unchained:payrexx');
|
|
6
6
|
|
|
7
7
|
export default (
|
|
8
|
-
baseUrl
|
|
8
|
+
baseUrl = 'https://api.payrexx.com/v1.0/',
|
|
9
9
|
instance: string = null,
|
|
10
10
|
secret: string = null,
|
|
11
11
|
): ((path: string, method: 'GET' | 'DELETE' | 'PUT' | 'POST', data?: any) => Promise<Response>) => {
|