@better-giving/donation 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/donation-msgs-db.d.mts +51 -0
- package/dist/donation-msgs-db.mjs +29 -0
- package/dist/donations-db.d.mts +18 -0
- package/dist/donations-db.mjs +108 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.mjs +2 -0
- package/dist/interfaces.d.mts +300 -0
- package/dist/interfaces.mjs +1 -0
- package/dist/onhold-db.d.mts +17 -0
- package/dist/onhold-db.mjs +88 -0
- package/dist/paypal.d.mts +73 -0
- package/dist/paypal.mjs +1 -0
- package/dist/schema.d.mts +38 -4
- package/dist/schema.mjs +14 -0
- package/dist/subscriptions-db.d.mts +11 -0
- package/dist/subscriptions-db.mjs +35 -0
- package/package.json +6 -3
- package/src/donation-msgs-db.mts +73 -0
- package/src/donations-db.mts +133 -0
- package/src/index.mts +14 -0
- package/src/interfaces.mts +316 -0
- package/src/onhold-db.mts +118 -0
- package/src/paypal.mts +85 -0
- package/src/schema.mts +36 -4
- package/src/subscriptions-db.mts +50 -0
- package/src/donation-message.mts +0 -39
- package/src/donation.mts +0 -483
- package/src/subscription.mts +0 -34
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Db } from "@better-giving/db";
|
|
2
|
+
import type { ISODate } from "@better-giving/types/alias";
|
|
3
|
+
import type { Environment } from "@better-giving/types/list";
|
|
4
|
+
import type { IPageOpts } from "./schema.mjs";
|
|
5
|
+
import type { IPageKeyed } from "@better-giving/types/api";
|
|
6
|
+
import type { IPublicDonor } from "./interfaces.mjs";
|
|
7
|
+
export type DMKey = `DM#${string}`;
|
|
8
|
+
export declare class DonationDonorsDb extends Db {
|
|
9
|
+
static readonly table = "donation_messages";
|
|
10
|
+
static readonly gsi1 = "gsi1";
|
|
11
|
+
key(id: string): {
|
|
12
|
+
readonly PK: `DM#${string}`;
|
|
13
|
+
readonly SK: `DM#${string}`;
|
|
14
|
+
};
|
|
15
|
+
gsi1_by_recipient(recipient: string, date: string): {
|
|
16
|
+
readonly gsi1PK: `Recipient#${string}#staging` | `Recipient#${string}#production`;
|
|
17
|
+
readonly gsi1SK: ISODate;
|
|
18
|
+
};
|
|
19
|
+
list(recipient: string, opts?: IPageOpts): Promise<IPageKeyed<IPublicDonor>>;
|
|
20
|
+
}
|
|
21
|
+
export declare namespace GSI1 {
|
|
22
|
+
type Name = "recipient-env-gsi";
|
|
23
|
+
interface Key {
|
|
24
|
+
/** `Recipient#{recipient_id}#{env}` */
|
|
25
|
+
gsi1PK: `Recipient#${string}#${Environment}`;
|
|
26
|
+
gsi1SK: ISODate;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export declare namespace DonationMessage {
|
|
30
|
+
/** `DM#{uuid}` */
|
|
31
|
+
interface PrimaryKey {
|
|
32
|
+
PK: DMKey;
|
|
33
|
+
SK: DMKey;
|
|
34
|
+
}
|
|
35
|
+
interface NonKeyAttributes {
|
|
36
|
+
/** USD amount at the time of donation */
|
|
37
|
+
amount: number;
|
|
38
|
+
date: ISODate;
|
|
39
|
+
donation_id: string;
|
|
40
|
+
donor_id: string;
|
|
41
|
+
donor_message: string;
|
|
42
|
+
donor_name: string;
|
|
43
|
+
env: Environment;
|
|
44
|
+
/** uuidv4 */
|
|
45
|
+
id: string;
|
|
46
|
+
/** Endow or fund ID */
|
|
47
|
+
recipient_id: string;
|
|
48
|
+
}
|
|
49
|
+
interface DBRecord extends PrimaryKey, NonKeyAttributes, GSI1.Key {
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Db } from "@better-giving/db";
|
|
2
|
+
import { QueryCommand } from "@aws-sdk/lib-dynamodb";
|
|
3
|
+
export class DonationDonorsDb extends Db {
|
|
4
|
+
static table = "donation_messages";
|
|
5
|
+
static gsi1 = "gsi1";
|
|
6
|
+
key(id) {
|
|
7
|
+
return { PK: `DM#${id}`, SK: `DM#${id}` };
|
|
8
|
+
}
|
|
9
|
+
gsi1_by_recipient(recipient, date) {
|
|
10
|
+
return {
|
|
11
|
+
gsi1PK: `Recipient#${recipient}#${this.env}`,
|
|
12
|
+
gsi1SK: date,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
list(recipient, opts) {
|
|
16
|
+
const cmd = new QueryCommand({
|
|
17
|
+
TableName: DonationDonorsDb.table,
|
|
18
|
+
IndexName: DonationDonorsDb.gsi1,
|
|
19
|
+
KeyConditionExpression: "gsi1PK = :gsi1PK",
|
|
20
|
+
ExpressionAttributeValues: {
|
|
21
|
+
":gsi1PK": this.gsi1_by_recipient(recipient, "only-sk-is-used").gsi1PK,
|
|
22
|
+
},
|
|
23
|
+
Limit: opts?.limit,
|
|
24
|
+
ExclusiveStartKey: this.key_to_obj(opts?.next),
|
|
25
|
+
ScanIndexForward: false,
|
|
26
|
+
});
|
|
27
|
+
return this.client.send(cmd).then((this.to_page));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Db } from "@better-giving/db";
|
|
2
|
+
import type { IDonationFinal, IDonationFinalAttr, TExplicit } from "./interfaces.mjs";
|
|
3
|
+
import { type QueryCommandInput } from "@aws-sdk/lib-dynamodb";
|
|
4
|
+
import type { IPageKeyed } from "@better-giving/types/api";
|
|
5
|
+
import type { IDonationsSearch } from "./schema.mjs";
|
|
6
|
+
export declare class DonationsDb extends Db {
|
|
7
|
+
static readonly table = "Donations";
|
|
8
|
+
static readonly gsi_referrer$settled_date = "Referrer-FinalizedDate_index";
|
|
9
|
+
static readonly gsi_npo$settled_date = "npo-settled_date-gsi";
|
|
10
|
+
static readonly gsi_email$tx_date = "email-tx_date-gsii";
|
|
11
|
+
put_txi(data: TExplicit<IDonationFinalAttr>): Promise<import("@aws-sdk/lib-dynamodb").PutCommandOutput>;
|
|
12
|
+
referred_by_q(referrer: string): Promise<QueryCommandInput>;
|
|
13
|
+
list_to_npo(npo: number, opts?: IDonationsSearch & {
|
|
14
|
+
date_start?: string;
|
|
15
|
+
date_end?: string;
|
|
16
|
+
}): Promise<IPageKeyed<IDonationFinal>>;
|
|
17
|
+
list_by_email(email: string, opts?: IDonationsSearch): Promise<IPageKeyed<IDonationFinal>>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Db } from "@better-giving/db";
|
|
2
|
+
import { PutCommand, QueryCommand, } from "@aws-sdk/lib-dynamodb";
|
|
3
|
+
export class DonationsDb extends Db {
|
|
4
|
+
static table = "Donations";
|
|
5
|
+
static gsi_referrer$settled_date = "Referrer-FinalizedDate_index";
|
|
6
|
+
static gsi_npo$settled_date = "npo-settled_date-gsi";
|
|
7
|
+
static gsi_email$tx_date = "email-tx_date-gsii";
|
|
8
|
+
async put_txi(data) {
|
|
9
|
+
const cmd = new PutCommand({
|
|
10
|
+
TableName: DonationsDb.table,
|
|
11
|
+
Item: data,
|
|
12
|
+
ConditionExpression: `attribute_not_exists(${"transactionId"})`,
|
|
13
|
+
});
|
|
14
|
+
return this.client.send(cmd);
|
|
15
|
+
}
|
|
16
|
+
async referred_by_q(referrer) {
|
|
17
|
+
const q = {
|
|
18
|
+
TableName: DonationsDb.table,
|
|
19
|
+
IndexName: DonationsDb.gsi_referrer$settled_date,
|
|
20
|
+
KeyConditionExpression: "#referrer = :referrer",
|
|
21
|
+
ExpressionAttributeNames: {
|
|
22
|
+
"#referrer": "referrer",
|
|
23
|
+
},
|
|
24
|
+
ExpressionAttributeValues: {
|
|
25
|
+
":referrer": referrer,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
return q;
|
|
29
|
+
}
|
|
30
|
+
async list_to_npo(npo, opts) {
|
|
31
|
+
/** key condition expression */
|
|
32
|
+
let kce = "#npo = :npo";
|
|
33
|
+
/** expression attribute names */
|
|
34
|
+
const ean = {
|
|
35
|
+
"#npo": "endowmentId",
|
|
36
|
+
};
|
|
37
|
+
/** expression attribute values */
|
|
38
|
+
const eav = {
|
|
39
|
+
":npo": npo,
|
|
40
|
+
};
|
|
41
|
+
if (opts?.date_start && opts?.date_end) {
|
|
42
|
+
kce += " AND #settled_date BETWEEN :date_start AND :date_end";
|
|
43
|
+
ean["#settled_date"] = "donationFinalTxDate";
|
|
44
|
+
eav[":date_start"] = opts.date_start;
|
|
45
|
+
eav[":date_end"] = opts.date_end;
|
|
46
|
+
}
|
|
47
|
+
else if (opts?.date_start) {
|
|
48
|
+
kce += " AND #settled_date >= :date_start";
|
|
49
|
+
ean["#settled_date"] = "donationFinalTxDate";
|
|
50
|
+
eav[":date_start"] = opts.date_start;
|
|
51
|
+
}
|
|
52
|
+
else if (opts?.date_end) {
|
|
53
|
+
kce += " AND #settled_date <= :date_end";
|
|
54
|
+
ean["#settled_date"] = "donationFinalTxDate";
|
|
55
|
+
eav[":date_end"] = opts.date_end;
|
|
56
|
+
}
|
|
57
|
+
const cmd = new QueryCommand({
|
|
58
|
+
TableName: DonationsDb.table,
|
|
59
|
+
IndexName: DonationsDb.gsi_npo$settled_date,
|
|
60
|
+
KeyConditionExpression: kce,
|
|
61
|
+
ExpressionAttributeNames: ean,
|
|
62
|
+
ExpressionAttributeValues: eav,
|
|
63
|
+
Limit: opts?.limit,
|
|
64
|
+
ExclusiveStartKey: this.key_to_obj(opts?.next),
|
|
65
|
+
ScanIndexForward: false,
|
|
66
|
+
});
|
|
67
|
+
return this.client.send(cmd).then((this.to_page));
|
|
68
|
+
}
|
|
69
|
+
async list_by_email(email, opts) {
|
|
70
|
+
/** key condition expression */
|
|
71
|
+
let kce = "#email = :email";
|
|
72
|
+
/** expression attribute names */
|
|
73
|
+
const ean = {
|
|
74
|
+
"#email": "email",
|
|
75
|
+
};
|
|
76
|
+
/** expression attribute values */
|
|
77
|
+
const eav = {
|
|
78
|
+
":email": email,
|
|
79
|
+
};
|
|
80
|
+
if (opts?.date_start && opts?.date_end) {
|
|
81
|
+
kce += " AND #settled_date BETWEEN :date_start AND :date_end";
|
|
82
|
+
ean["#settled_date"] = "transactionDate";
|
|
83
|
+
eav[":date_start"] = opts.date_start;
|
|
84
|
+
eav[":date_end"] = opts.date_end;
|
|
85
|
+
}
|
|
86
|
+
else if (opts?.date_start) {
|
|
87
|
+
kce += " AND #settled_date >= :date_start";
|
|
88
|
+
ean["#settled_date"] = "transactionDate";
|
|
89
|
+
eav[":date_start"] = opts.date_start;
|
|
90
|
+
}
|
|
91
|
+
else if (opts?.date_end) {
|
|
92
|
+
kce += " AND #settled_date <= :date_end";
|
|
93
|
+
ean["#settled_date"] = "transactionDate";
|
|
94
|
+
eav[":date_end"] = opts.date_end;
|
|
95
|
+
}
|
|
96
|
+
const cmd = new QueryCommand({
|
|
97
|
+
TableName: DonationsDb.table,
|
|
98
|
+
IndexName: DonationsDb.gsi_email$tx_date,
|
|
99
|
+
KeyConditionExpression: kce,
|
|
100
|
+
ExpressionAttributeNames: ean,
|
|
101
|
+
ExpressionAttributeValues: eav,
|
|
102
|
+
Limit: opts?.limit,
|
|
103
|
+
ExclusiveStartKey: this.key_to_obj(opts?.next),
|
|
104
|
+
ScanIndexForward: false,
|
|
105
|
+
});
|
|
106
|
+
return this.client.send(cmd).then((this.to_page));
|
|
107
|
+
}
|
|
108
|
+
}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { IAllocation, TDonationSource, TDonorTitle, TFrequency, IDonationsSearch, IPageOpts, } from "./schema.mjs";
|
|
2
|
+
export type * from "./paypal.mjs";
|
|
3
|
+
export type * from "./interfaces.mjs";
|
|
4
|
+
export { DonationsDb } from "./donations-db.mjs";
|
|
5
|
+
export { OnHoldDonationsDb } from "./onhold-db.mjs";
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import type { Environment } from "@better-giving/types/list";
|
|
2
|
+
import type { IAllocation, TDonationSource, TDonorTitle } from "./schema.mjs";
|
|
3
|
+
interface IReferrerCommission {
|
|
4
|
+
from_tip: number;
|
|
5
|
+
from_fee: number;
|
|
6
|
+
/** exist when paid */
|
|
7
|
+
transfer_id?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ITributeNotif {
|
|
10
|
+
toEmail: string;
|
|
11
|
+
toFullName: string;
|
|
12
|
+
fromMsg: string;
|
|
13
|
+
}
|
|
14
|
+
export type TFiatRamp = "STRIPE" | "CHARIOT" | "PAYPAL";
|
|
15
|
+
export type TOnHoldStatus = "intent" | "pending";
|
|
16
|
+
export type TDonationOnholdStatus = "intent" | "pending";
|
|
17
|
+
export interface IDonationOnHoldAttrLegacy {
|
|
18
|
+
/** @deprecated */
|
|
19
|
+
apesComplianceReviewStatus?: "approved";
|
|
20
|
+
/** @deprecated */
|
|
21
|
+
apesComplianceTimeWindow?: string;
|
|
22
|
+
/** @deprecated */
|
|
23
|
+
client?: "apes";
|
|
24
|
+
/** @deprecated */
|
|
25
|
+
destinationChainId?: "fiat" | "137";
|
|
26
|
+
/** @deprecated */
|
|
27
|
+
donationFinalized?: false;
|
|
28
|
+
/** @deprecated 1-100 str */
|
|
29
|
+
splitLiq?: string;
|
|
30
|
+
/** @deprecated - no more inhouse pipeline */
|
|
31
|
+
third_party?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface IDonationOnHoldAttr {
|
|
34
|
+
transactionDate: string;
|
|
35
|
+
transactionId: string;
|
|
36
|
+
allocation?: IAllocation;
|
|
37
|
+
amount: number;
|
|
38
|
+
status: TOnHoldStatus;
|
|
39
|
+
tipAmount: number;
|
|
40
|
+
/**
|
|
41
|
+
"USD", "TRX", "karate-295", "BRL", "GBP", "USDC", "JPY", "ETH", "USDCMATIC", "EUR", "INR", "THB", "PHP",
|
|
42
|
+
"XRP", "RUB", "CAD", "karate-1" ... */
|
|
43
|
+
denomination: string;
|
|
44
|
+
/** bg-marketplace | bg-widget */
|
|
45
|
+
appUsed: TDonationSource;
|
|
46
|
+
/** "fiat", "trx", "hbar", "eth", "matic", "xrp-mainnet" */
|
|
47
|
+
chainId: string;
|
|
48
|
+
/** "Fiat", "TRON", "Hedera", "Ethereum", "", "Polygon", "Stripe", "XRP Ledger" */
|
|
49
|
+
chainName: string;
|
|
50
|
+
charityName: string;
|
|
51
|
+
claimed?: boolean;
|
|
52
|
+
/** may be empty */
|
|
53
|
+
company_name?: string;
|
|
54
|
+
donor_public?: boolean;
|
|
55
|
+
kycEmail: string;
|
|
56
|
+
/** @legacy */
|
|
57
|
+
email?: string;
|
|
58
|
+
/** 0 when donating to fund */
|
|
59
|
+
endowmentId: number;
|
|
60
|
+
fiatRamp?: TFiatRamp;
|
|
61
|
+
feeAllowance?: number;
|
|
62
|
+
fiscalSponsored: boolean;
|
|
63
|
+
fullName: string;
|
|
64
|
+
/** may be empty, if donation is to npo */
|
|
65
|
+
fund_id?: string;
|
|
66
|
+
fund_members?: number[];
|
|
67
|
+
fund_name?: string;
|
|
68
|
+
hideBgTip?: boolean;
|
|
69
|
+
/** may be empty */
|
|
70
|
+
inHonorOf?: string;
|
|
71
|
+
isRecurring?: boolean;
|
|
72
|
+
msg_to_npo?: string;
|
|
73
|
+
network: Environment;
|
|
74
|
+
/** may be empty */
|
|
75
|
+
nonProfitMsg?: string;
|
|
76
|
+
/** Nowpayments: number, custom: uuid */
|
|
77
|
+
payment_id?: number | string;
|
|
78
|
+
/** e.g. Bank transfer */
|
|
79
|
+
paymentMethod?: string;
|
|
80
|
+
/** may be empty */
|
|
81
|
+
programId?: string;
|
|
82
|
+
/** may be empty */
|
|
83
|
+
programName?: string;
|
|
84
|
+
stripeDepositVerifyUrl?: string;
|
|
85
|
+
/** TTL attribute */
|
|
86
|
+
expireAt?: number;
|
|
87
|
+
title?: TDonorTitle;
|
|
88
|
+
tributeNotif?: ITributeNotif;
|
|
89
|
+
ukGiftAid?: boolean;
|
|
90
|
+
usdValue: number;
|
|
91
|
+
/** may be empty */
|
|
92
|
+
walletAddress?: string;
|
|
93
|
+
}
|
|
94
|
+
export interface IDonationOnHold extends IDonationOnHoldAttr, IDonationOnHoldAttrLegacy {
|
|
95
|
+
}
|
|
96
|
+
export interface IDonationFinalAttrLegacy {
|
|
97
|
+
/** @deprecated "", " "*/
|
|
98
|
+
addressComplement?: string;
|
|
99
|
+
/** @deprecated 4 */
|
|
100
|
+
apesComplianceNewRecipient?: 4;
|
|
101
|
+
/** @deprecated "approved", "pending" */
|
|
102
|
+
apesComplianceReviewStatus?: string;
|
|
103
|
+
/** @deprecated */
|
|
104
|
+
apesComplianceTimeWindow?: string;
|
|
105
|
+
/** @deprecated */
|
|
106
|
+
charityId?: string | number;
|
|
107
|
+
/** @deprecated */
|
|
108
|
+
checked8283?: "no" | "yes";
|
|
109
|
+
/** @deprecated */
|
|
110
|
+
client?: "apes" | "normal";
|
|
111
|
+
/** @deprecated */
|
|
112
|
+
consent_marketing?: boolean;
|
|
113
|
+
/** @deprecated */
|
|
114
|
+
consent_tax?: boolean;
|
|
115
|
+
/** @deprecated */
|
|
116
|
+
cryptoFee?: number;
|
|
117
|
+
/** @deprecated - all donations in this table are settled/final */
|
|
118
|
+
donationFinalized?: boolean;
|
|
119
|
+
/** @deprecated */
|
|
120
|
+
fiscalSponsorshipFee?: number;
|
|
121
|
+
/** @deprecated */
|
|
122
|
+
fundDepositTxHash?: string;
|
|
123
|
+
/** @deprecated */
|
|
124
|
+
fundId?: number;
|
|
125
|
+
/** @deprecated */
|
|
126
|
+
fundMembers?: string[];
|
|
127
|
+
/** @deprecated may be empty */
|
|
128
|
+
nftAddress?: string;
|
|
129
|
+
nftRequested?: boolean;
|
|
130
|
+
/** @deprecated */
|
|
131
|
+
receiptRequested?: boolean;
|
|
132
|
+
/** @deprecated */
|
|
133
|
+
splitLiq?: string;
|
|
134
|
+
/** @deprecated "null", "UST", "axlUSDC", "USDC", "nulll" */
|
|
135
|
+
swapDenomination?: string;
|
|
136
|
+
/** @deprecated */
|
|
137
|
+
swapFinalAmount?: number;
|
|
138
|
+
/** @deprecated */
|
|
139
|
+
swapFinished?: boolean;
|
|
140
|
+
/** @deprecated */
|
|
141
|
+
swapStarted?: boolean;
|
|
142
|
+
/** @deprecated */
|
|
143
|
+
taxReceiptSent?: "yes" | "no";
|
|
144
|
+
/** @deprecated e.g. "White Whale", "Plutos Pot / Lunaverse", "Spaar"..*/
|
|
145
|
+
tcaAssociation?: string;
|
|
146
|
+
/** @deprecated */
|
|
147
|
+
ustFinal?: number;
|
|
148
|
+
/** @deprecated */
|
|
149
|
+
walletAddress?: string;
|
|
150
|
+
}
|
|
151
|
+
export type TExplicit<T> = {
|
|
152
|
+
[K in keyof T]-?: T[K];
|
|
153
|
+
};
|
|
154
|
+
export interface IDonationFinalAttr {
|
|
155
|
+
amount?: number;
|
|
156
|
+
allocation?: IAllocation;
|
|
157
|
+
/** "bg-marketplace", "restore-earth", "angel-protocol",
|
|
158
|
+
"ukraine-portal", "bg-widget", undefined, "aging", "black-history-month",
|
|
159
|
+
"make-whole", "mental-health" */
|
|
160
|
+
appUsed?: TDonationSource | (string & {});
|
|
161
|
+
baseFee?: number;
|
|
162
|
+
/**
|
|
163
|
+
"fiat", "columbus-5", "eth", "matic", "juno-1", "ltc", undefined, "btc", "phoenix-1", "56", "1", "137",
|
|
164
|
+
"xrp-mainnet", "zec", "sol", "bch", "bsc", "cchain", "xvg", "xrp", "sei-1", "icx", "base",
|
|
165
|
+
"trx", "avaxc""
|
|
166
|
+
*/
|
|
167
|
+
chainId?: string;
|
|
168
|
+
/**
|
|
169
|
+
"Fiat", "Terra Mainnet", "STRIPE", "Ethereum Mainnet",
|
|
170
|
+
"Polygon", "Juno Mainnet", "Litecoin", undefined, "Ethereum", "Bitcoin", "Terra Phoenix Mainnet",
|
|
171
|
+
"Binance Smart Chain", "Polygon Mainnet", "XRP Ledger",
|
|
172
|
+
"Zcash", "Solana", "BNB Smart Chain Mainnet", "Bitcoin Cash",
|
|
173
|
+
"Avalanche C-Chain", "Verge", "XRP", "Sei", "ICON", "Base", "TRON", "CHARIOT"
|
|
174
|
+
*/
|
|
175
|
+
chainName?: string;
|
|
176
|
+
charityName?: string;
|
|
177
|
+
/** may be empty */
|
|
178
|
+
city?: string;
|
|
179
|
+
claimed?: boolean;
|
|
180
|
+
/** may be empty */
|
|
181
|
+
company_name?: string;
|
|
182
|
+
/** may be empty */
|
|
183
|
+
country?: string;
|
|
184
|
+
donor_public?: boolean;
|
|
185
|
+
donor_message?: string;
|
|
186
|
+
/**
|
|
187
|
+
PHP", "UST", "USD", "LUNA", "ETH", "USDCMATIC", "axlUSDC", "LTC", undefined, "EUR", "NZD", "JUNO", "INR",
|
|
188
|
+
"IDR", "GBP", "USDTMATIC", "PKR", "BTC", "SEK", "HKD", "SGD", "BNB", "CAD", "MATICMAINNET",
|
|
189
|
+
"USDC", "MOP", "XRP", "JPY", "MATIC", "RSD", "ZEC", "TWD", "SOL", "AUD", "KRW", "BCH", "CHF", "TEL", "USDTBSC",
|
|
190
|
+
"YER", "ATOM", "AVAXC", "USDTERC20", "XVG", "BUSD", "SEI", "ICX", "ETHBASE", "USDC.e", "USDCBASE", "TRX",
|
|
191
|
+
"VND", "SZL", "GONE", "AFN", "PLN", "NOK", "WETH", "EGP", "BUSDBSC", "USDCARC20", "USDTTRC20", "THB"
|
|
192
|
+
*/
|
|
193
|
+
denomination?: string;
|
|
194
|
+
donationFinalAmount?: number;
|
|
195
|
+
/**
|
|
196
|
+
"fiat", undefined, "matic", "137", "noble-1", "eth"*/
|
|
197
|
+
destinationChainId?: string;
|
|
198
|
+
/** "fiat", undefined, "matic", "juno-1", "137", "noble-1", "eth" */
|
|
199
|
+
donationFinalChainId?: string;
|
|
200
|
+
/**
|
|
201
|
+
* "USD", "aUSDC", "USDC", "axlUSDC"
|
|
202
|
+
*/
|
|
203
|
+
donationFinalDenom?: string;
|
|
204
|
+
/** iso date */
|
|
205
|
+
donationFinalTxDate?: string;
|
|
206
|
+
donationFinalTxHash?: string;
|
|
207
|
+
endowmentId?: number;
|
|
208
|
+
excessFeeAllowanceUsd?: number;
|
|
209
|
+
feeAllowance?: number;
|
|
210
|
+
fiatRamp?: TFiatRamp;
|
|
211
|
+
fiscalSponsored?: boolean;
|
|
212
|
+
fiscalSponsorFee?: number;
|
|
213
|
+
/** may be empty */
|
|
214
|
+
fullName?: string;
|
|
215
|
+
fund_id?: string;
|
|
216
|
+
fund_name?: string;
|
|
217
|
+
fund_members?: number[];
|
|
218
|
+
/** may be empty */
|
|
219
|
+
inHonorOf?: string;
|
|
220
|
+
isRecurring?: boolean;
|
|
221
|
+
kycEmail?: string;
|
|
222
|
+
/** @warning, about 14 legacy records (~2021) contain invalid email */
|
|
223
|
+
email?: string;
|
|
224
|
+
msg_to_npo?: string;
|
|
225
|
+
network?: Environment;
|
|
226
|
+
/** may be empty */
|
|
227
|
+
nonProfitMsg?: string;
|
|
228
|
+
/** indicates this is a tip record */
|
|
229
|
+
parentTx?: string;
|
|
230
|
+
/**
|
|
231
|
+
"Credit Card", undefined, "Stripe Link", "Bank Transfer",
|
|
232
|
+
"Crypto", "Debit Card", "link", "Card", "Bank", "crypto", "Amazon Pay", "Daf", "Affirm", "eps", "card",
|
|
233
|
+
"p24", "affirm"
|
|
234
|
+
*/
|
|
235
|
+
paymentMethod?: string;
|
|
236
|
+
processingFee?: number;
|
|
237
|
+
/** may be empty */
|
|
238
|
+
programId?: string;
|
|
239
|
+
/** may be empty */
|
|
240
|
+
programName?: string;
|
|
241
|
+
referrer_commission?: IReferrerCommission;
|
|
242
|
+
referrer?: string;
|
|
243
|
+
settledUsdAmount?: number;
|
|
244
|
+
state?: string;
|
|
245
|
+
/** @legacy may be empty */
|
|
246
|
+
stateAddress?: string;
|
|
247
|
+
streetAddress?: string;
|
|
248
|
+
taxReceiptId?: string;
|
|
249
|
+
/** Mr Ms Mrs Mx, may be empty */
|
|
250
|
+
title?: string;
|
|
251
|
+
/** iso */
|
|
252
|
+
transactionDate?: string;
|
|
253
|
+
transactionId: string;
|
|
254
|
+
tributeNotif?: ITributeNotif;
|
|
255
|
+
ukGiftAid?: boolean;
|
|
256
|
+
usdValue?: number;
|
|
257
|
+
/** may be empty */
|
|
258
|
+
zipCode?: string;
|
|
259
|
+
}
|
|
260
|
+
export interface IDonationFinal extends IDonationFinalAttr, IDonationFinalAttrLegacy {
|
|
261
|
+
}
|
|
262
|
+
export interface IPublicDonor {
|
|
263
|
+
amount: number;
|
|
264
|
+
/** iso */
|
|
265
|
+
date: string;
|
|
266
|
+
donation_id: string;
|
|
267
|
+
donor_id: string;
|
|
268
|
+
donor_message: string;
|
|
269
|
+
donor_name: string;
|
|
270
|
+
env: Environment;
|
|
271
|
+
/** uuidv4 */
|
|
272
|
+
id: string;
|
|
273
|
+
/** Endow or fund ID */
|
|
274
|
+
recipient_id: string;
|
|
275
|
+
}
|
|
276
|
+
export interface ISubscription {
|
|
277
|
+
subscription_id: string;
|
|
278
|
+
app_used: string;
|
|
279
|
+
charity_name: string;
|
|
280
|
+
customer_id: string;
|
|
281
|
+
email: string;
|
|
282
|
+
endowment_id: number;
|
|
283
|
+
fiat_ramp: "STRIPE";
|
|
284
|
+
fiscal_sponsored: boolean;
|
|
285
|
+
hide_bg_tip: boolean;
|
|
286
|
+
/** url*/
|
|
287
|
+
latest_invoice?: string;
|
|
288
|
+
network: Environment;
|
|
289
|
+
product_id: string;
|
|
290
|
+
/**
|
|
291
|
+
* Determines overall price the user has to pay
|
|
292
|
+
* For example, we have a recurring subscription plan of $1 per month.
|
|
293
|
+
* If quantity is set to 2 then the user pays $2 per month
|
|
294
|
+
*/
|
|
295
|
+
quantity: number;
|
|
296
|
+
split_liq: string;
|
|
297
|
+
/** @link https://docs.stripe.com/billing/subscriptions/overview#payment-status */
|
|
298
|
+
status: "active" | "incomplete";
|
|
299
|
+
}
|
|
300
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Db, type TxType } from "@better-giving/db";
|
|
2
|
+
import type { IDonationOnHold, IDonationOnHoldAttr, TExplicit } from "./interfaces.mjs";
|
|
3
|
+
import type { IDonationsSearch } from "./schema.mjs";
|
|
4
|
+
import type { IPageKeyed } from "@better-giving/types/api";
|
|
5
|
+
export declare class OnHoldDonationsDb extends Db {
|
|
6
|
+
static readonly table = "on_hold_donations";
|
|
7
|
+
static readonly gsi_email$tx_date = "email-tx_date-gsi";
|
|
8
|
+
key(id: string): {
|
|
9
|
+
transactionId: string;
|
|
10
|
+
};
|
|
11
|
+
put(data: TExplicit<IDonationOnHoldAttr>): Promise<import("@aws-sdk/lib-dynamodb").PutCommandOutput>;
|
|
12
|
+
update(id: string, data: Partial<Omit<IDonationOnHoldAttr, "transactionId">>): Promise<IDonationOnHold>;
|
|
13
|
+
item(id: string): Promise<IDonationOnHold | undefined>;
|
|
14
|
+
put_txi(data: TExplicit<IDonationOnHoldAttr>): Promise<import("@aws-sdk/lib-dynamodb").PutCommandOutput>;
|
|
15
|
+
del_txi(id: string): TxType["Delete"];
|
|
16
|
+
list_by_email(email: string, opts?: IDonationsSearch): Promise<IPageKeyed<IDonationOnHold>>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Db, UpdateBuilder } from "@better-giving/db";
|
|
2
|
+
import { GetCommand, PutCommand, QueryCommand, UpdateCommand, } from "@aws-sdk/lib-dynamodb";
|
|
3
|
+
export class OnHoldDonationsDb extends Db {
|
|
4
|
+
static table = "on_hold_donations";
|
|
5
|
+
static gsi_email$tx_date = "email-tx_date-gsi";
|
|
6
|
+
key(id) {
|
|
7
|
+
return { transactionId: id };
|
|
8
|
+
}
|
|
9
|
+
async put(data) {
|
|
10
|
+
const cmd = new PutCommand({
|
|
11
|
+
TableName: OnHoldDonationsDb.table,
|
|
12
|
+
Item: data,
|
|
13
|
+
ConditionExpression: `attribute_not_exists(${"transactionId"})`,
|
|
14
|
+
});
|
|
15
|
+
return this.client.send(cmd);
|
|
16
|
+
}
|
|
17
|
+
async update(id, data) {
|
|
18
|
+
const upd8 = new UpdateBuilder();
|
|
19
|
+
for (const k in data) {
|
|
20
|
+
upd8.set(k, data[k]);
|
|
21
|
+
}
|
|
22
|
+
const cmd = new UpdateCommand({
|
|
23
|
+
TableName: OnHoldDonationsDb.table,
|
|
24
|
+
Key: this.key(id),
|
|
25
|
+
...upd8.collect(),
|
|
26
|
+
});
|
|
27
|
+
return this.client.send(cmd).then((r) => r.Attributes);
|
|
28
|
+
}
|
|
29
|
+
async item(id) {
|
|
30
|
+
const cmd = new GetCommand({
|
|
31
|
+
TableName: OnHoldDonationsDb.table,
|
|
32
|
+
Key: this.key(id),
|
|
33
|
+
});
|
|
34
|
+
return this.client.send(cmd).then((r) => r.Item);
|
|
35
|
+
}
|
|
36
|
+
put_txi(data) {
|
|
37
|
+
const cmd = new PutCommand({
|
|
38
|
+
TableName: OnHoldDonationsDb.table,
|
|
39
|
+
Item: data,
|
|
40
|
+
ConditionExpression: `attribute_not_exists(${"transactionId"})`,
|
|
41
|
+
});
|
|
42
|
+
return this.client.send(cmd);
|
|
43
|
+
}
|
|
44
|
+
del_txi(id) {
|
|
45
|
+
return { TableName: OnHoldDonationsDb.table, Key: this.key(id) };
|
|
46
|
+
}
|
|
47
|
+
async list_by_email(email, opts) {
|
|
48
|
+
/** key condition expression */
|
|
49
|
+
let kce = "#email = :email";
|
|
50
|
+
/** expression attribute names */
|
|
51
|
+
const ean = {
|
|
52
|
+
"#email": "email",
|
|
53
|
+
};
|
|
54
|
+
/** expression attribute values */
|
|
55
|
+
const eav = {
|
|
56
|
+
":email": email,
|
|
57
|
+
};
|
|
58
|
+
if (opts?.date_start && opts?.date_end) {
|
|
59
|
+
kce += " AND #settled_date BETWEEN :date_start AND :date_end";
|
|
60
|
+
ean["#settled_date"] = "transactionDate";
|
|
61
|
+
eav[":date_start"] = opts.date_start;
|
|
62
|
+
eav[":date_end"] = opts.date_end;
|
|
63
|
+
}
|
|
64
|
+
else if (opts?.date_start) {
|
|
65
|
+
kce += " AND #settled_date >= :date_start";
|
|
66
|
+
ean["#settled_date"] = "transactionDate";
|
|
67
|
+
eav[":date_start"] = opts.date_start;
|
|
68
|
+
}
|
|
69
|
+
else if (opts?.date_end) {
|
|
70
|
+
kce += " AND #settled_date <= :date_end";
|
|
71
|
+
ean["#settled_date"] = "transactionDate";
|
|
72
|
+
eav[":date_end"] = opts.date_end;
|
|
73
|
+
}
|
|
74
|
+
const cmd = new QueryCommand({
|
|
75
|
+
TableName: OnHoldDonationsDb.table,
|
|
76
|
+
IndexName: OnHoldDonationsDb.gsi_email$tx_date,
|
|
77
|
+
KeyConditionExpression: "#email = :email",
|
|
78
|
+
ExpressionAttributeNames: {
|
|
79
|
+
"#email": "email",
|
|
80
|
+
},
|
|
81
|
+
ExpressionAttributeValues: {
|
|
82
|
+
":email": email,
|
|
83
|
+
},
|
|
84
|
+
ScanIndexForward: false,
|
|
85
|
+
});
|
|
86
|
+
return this.client.send(cmd).then((this.to_page));
|
|
87
|
+
}
|
|
88
|
+
}
|