Skip to content

Commit 57f04ff

Browse files
authored
New Components - ifthenpay (#16393)
* ifthenpay init * [Components] ifthenpay #16383 Sources - New Payment Actions - Create Payment Reference - Issue Refund * pnpm update * some adjusts * some adjusts
1 parent dcec868 commit 57f04ff

File tree

13 files changed

+370
-12
lines changed

13 files changed

+370
-12
lines changed

components/bika_ai/bika_ai.app.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ export default {
88
console.log(Object.keys(this.$auth));
99
},
1010
},
11-
};
11+
};
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import { PAYMENT_METHOD_OPTIONS } from "../../common/constants.mjs";
2+
import ifthenpay from "../../ifthenpay.app.mjs";
3+
4+
export default {
5+
key: "ifthenpay-create-payment-reference",
6+
name: "Create Payment Reference",
7+
description: "Generates a Multibanco or MB WAY payment reference with a specified amount, entity code, and deadline. [See the documentation](https://ifthenpay.com/docs/en/)",
8+
version: "0.0.1",
9+
type: "action",
10+
props: {
11+
ifthenpay,
12+
paymentMethod: {
13+
type: "string",
14+
label: "Payment Method",
15+
description: "The payment method to use for Ifthenpay (e.g., MB WAY, Multibanco)",
16+
options: PAYMENT_METHOD_OPTIONS,
17+
reloadProps: true,
18+
},
19+
mbKey: {
20+
propDefinition: [
21+
ifthenpay,
22+
"mbKey",
23+
],
24+
hidden: true,
25+
},
26+
mbWayKey: {
27+
propDefinition: [
28+
ifthenpay,
29+
"mbWayKey",
30+
],
31+
hidden: true,
32+
},
33+
orderId: {
34+
type: "string",
35+
label: "Order Id",
36+
description: "Payment identifier defined by the client (e.g., invoice number, order number, etc.)",
37+
},
38+
amount: {
39+
type: "string",
40+
label: "Amount",
41+
description: "The amount to be paid with decimal separator \".\"",
42+
},
43+
mobileNumber: {
44+
type: "string",
45+
label: "Mobile Number",
46+
description: "Place the country code before the mobile number without any spaces (use '#'' to separate the country code from the mobile number - p.e. 351#912345678)",
47+
hidden: true,
48+
},
49+
description: {
50+
type: "string",
51+
label: "Description",
52+
description: "Description of the payment, with a maximum length of 200 characters",
53+
optional: true,
54+
},
55+
url: {
56+
type: "string",
57+
label: "URL",
58+
description: "URL address, with a maximum length of 200 characters",
59+
optional: true,
60+
hidden: true,
61+
},
62+
clientCode: {
63+
type: "string",
64+
label: "Client Code",
65+
description: "Client's code, with a maximum length of 200 characters",
66+
optional: true,
67+
hidden: true,
68+
},
69+
clientName: {
70+
type: "string",
71+
label: "Client Name",
72+
description: "Client's name, with a maximum length of 200 characters",
73+
optional: true,
74+
hidden: true,
75+
},
76+
email: {
77+
type: "string",
78+
label: "Email",
79+
description: "The Client's name.",
80+
optional: true,
81+
},
82+
clientUsername: {
83+
type: "string",
84+
label: "Client Username",
85+
description: "Client's username, with a maximum length of 200 characters",
86+
optional: true,
87+
hidden: true,
88+
},
89+
clientPhone: {
90+
type: "string",
91+
label: "Client Phone",
92+
description: "Client's cell phone or phone number, with a maximum length of 200 characters",
93+
optional: true,
94+
hidden: true,
95+
},
96+
expiryDays: {
97+
type: "integer",
98+
label: "Expiry Days",
99+
description: "How many days the payment reference is valid for. [See the documentation](https://ifthenpay.com/docs/en/api/multibanco/#tag/multibanco/POST/init) for further details.",
100+
optional: true,
101+
hidden: true,
102+
},
103+
},
104+
async additionalProps(props) {
105+
const isMb = this.paymentMethod === "Multibanco";
106+
props.mbKey.hidden = !isMb;
107+
props.mbWayKey.hidden = isMb;
108+
props.mobileNumber.hidden = isMb;
109+
props.url.hidden = isMb;
110+
props.clientCode.hidden = isMb;
111+
props.clientName.hidden = isMb;
112+
props.email.label = "Client Email";
113+
props.email.description = "Client's email address, with a maximum length of 200 characters";
114+
props.clientUsername.hidden = isMb;
115+
props.clientPhone.hidden = isMb;
116+
props.expiryDays.hidden = isMb;
117+
return {};
118+
},
119+
async run({ $ }) {
120+
const response = await this.ifthenpay.generatePaymentReference({
121+
$,
122+
paymentMethod: this.paymentMethod,
123+
data: {
124+
mbKey: this.mbKey,
125+
mbWayKey: this.mbWayKey,
126+
orderId: this.orderId,
127+
amount: parseFloat(this.amount),
128+
mobileNumber: this.mobileNumber,
129+
email: this.email,
130+
description: this.description,
131+
url: this.url,
132+
clientCode: this.clientCode,
133+
clientName: this.clientName,
134+
clientUsername: this.clientUsername,
135+
clientPhone: this.clientPhone,
136+
expiryDays: this.expiryDays,
137+
expirationDate: this.expirationDate,
138+
clientEmail: this.email,
139+
},
140+
});
141+
142+
$.export("$summary", `Successfully created payment reference with Order ID: ${response.OrderId}`);
143+
return response;
144+
},
145+
};
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import ifthenpay from "../../ifthenpay.app.mjs";
2+
3+
export default {
4+
key: "ifthenpay-issue-refund",
5+
name: "Issue Refund",
6+
description: "Issue a full or partial refund for a previously completed payment via Ifthenpay. [See the documentation](https://ifthenpay.com/docs/en/)",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
ifthenpay,
11+
requestId: {
12+
propDefinition: [
13+
ifthenpay,
14+
"requestId",
15+
],
16+
},
17+
amount: {
18+
type: "string",
19+
label: "Amount",
20+
description: "The amount to be refunded.",
21+
},
22+
},
23+
async run({ $ }) {
24+
const response = await this.ifthenpay.refundPayment({
25+
$,
26+
data: {
27+
backofficekey: this.ifthenpay.$auth.backoffice_key,
28+
requestId: this.requestId,
29+
amount: this.amount,
30+
},
31+
});
32+
33+
$.export("$summary", `Successfully issued a refund for payment ID: ${this.requestId}`);
34+
return response;
35+
},
36+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const PAYMENT_METHOD_OPTIONS = [
2+
"MB WAY",
3+
"Multibanco",
4+
];
Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,101 @@
1+
import { axios } from "@pipedream/platform";
2+
13
export default {
24
type: "app",
35
app: "ifthenpay",
4-
propDefinitions: {},
6+
propDefinitions: {
7+
requestId: {
8+
type: "string",
9+
label: "Request ID",
10+
description: "Token associated with the payment request transaction",
11+
async options({ prevContext }) {
12+
const { payments } = await this.listPayments({
13+
data: {
14+
dateStart: prevContext.token,
15+
},
16+
});
17+
18+
return {
19+
options: payments.map(({
20+
requestId: value, orderId: label,
21+
}) => ({
22+
label,
23+
value,
24+
})),
25+
context: {
26+
token: payments.length
27+
? payments[0].paymentDate
28+
: null,
29+
},
30+
};
31+
},
32+
},
33+
mbWayKey: {
34+
type: "string",
35+
label: "Mb Way Key",
36+
description: "The key for the MB Way payment method.",
37+
secret: true,
38+
},
39+
mbKey: {
40+
type: "string",
41+
label: "Mb Key",
42+
description: "The key for the Multibanco payment method.",
43+
secret: true,
44+
},
45+
},
546
methods: {
6-
// this.$auth contains connected account data
7-
authKeys() {
8-
console.log(Object.keys(this.$auth));
47+
_baseUrl() {
48+
return "https://api.ifthenpay.com";
49+
},
50+
_data(data) {
51+
return {
52+
"boKey": `${this.$auth.backoffice_key}`,
53+
...data,
54+
};
55+
},
56+
_makeRequest({
57+
$ = this, path, data, ...opts
58+
}) {
59+
return axios($, {
60+
url: this._baseUrl() + path,
61+
headers: {
62+
"accept": "application/json",
63+
},
64+
data: this._data(data),
65+
...opts,
66+
});
67+
},
68+
generatePaymentReference({
69+
paymentMethod, data, ...opts
70+
}) {
71+
let path;
72+
if (paymentMethod === "Multibanco") {
73+
path = "/multibanco/reference/init";
74+
} else if (paymentMethod === "MB WAY") {
75+
path = "/spg/payment/mbway";
76+
}
77+
78+
return this._makeRequest({
79+
method: "POST",
80+
path,
81+
data,
82+
...opts,
83+
});
84+
},
85+
refundPayment(opts = {}) {
86+
return this._makeRequest({
87+
method: "POST",
88+
path: "/endpoint/payments/refund",
89+
...opts,
90+
});
91+
},
92+
listPayments(opts = {}) {
93+
return this._makeRequest({
94+
method: "POST",
95+
path: "/v2/payments/read",
96+
...opts,
97+
});
998
},
1099
},
11100
};
101+

components/ifthenpay/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/ifthenpay",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Pipedream ifthenpay Components",
55
"main": "ifthenpay.app.mjs",
66
"keywords": [
@@ -11,5 +11,8 @@
1111
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)",
1212
"publishConfig": {
1313
"access": "public"
14+
},
15+
"dependencies": {
16+
"@pipedream/platform": "^3.0.3"
1417
}
15-
}
18+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform";
2+
import ifthenpay from "../../ifthenpay.app.mjs";
3+
import sampleEmit from "./test-event.mjs";
4+
5+
export default {
6+
key: "ifthenpay-new-payment",
7+
name: "New Payment Completed",
8+
description: "Emit new event when a payment is successfully completed through Ifthenpay. [See the documentation](https://ifthenpay.com/docs/en/)",
9+
version: "0.0.1",
10+
type: "source",
11+
dedupe: "unique",
12+
props: {
13+
ifthenpay,
14+
db: "$.service.db",
15+
timer: {
16+
type: "$.interface.timer",
17+
default: {
18+
intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL,
19+
},
20+
},
21+
},
22+
methods: {
23+
_getLastDate() {
24+
return this.db.get("lastDate") || "1970-01-01 00:00:00";
25+
},
26+
_setLastDate(lastDate) {
27+
this.db.set("lastDate", lastDate);
28+
},
29+
async emitEvent(maxResults = false) {
30+
const lastDate = this._getLastDate();
31+
32+
const { payments: response } = await this.ifthenpay.listPayments({
33+
data: {
34+
dateStart: lastDate,
35+
},
36+
});
37+
38+
if (response.length) {
39+
if (maxResults && (response.length > maxResults)) {
40+
response.length = maxResults;
41+
}
42+
this._setLastDate(response[0].paymentDate);
43+
}
44+
45+
for (const item of response.reverse()) {
46+
this.$emit(item, {
47+
id: item.requestId,
48+
summary: `New Payment: ${parseFloat(item.amount)} ${item.entity}`,
49+
ts: Date.parse(item.paymentDate),
50+
});
51+
}
52+
},
53+
},
54+
hooks: {
55+
async deploy() {
56+
await this.emitEvent(25);
57+
},
58+
},
59+
async run() {
60+
await this.emitEvent();
61+
},
62+
sampleEmit,
63+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
export default {
2+
"amount": 22750,
3+
"entity": "MB",
4+
"fee": 0.86,
5+
"netAmount": 22749.14,
6+
"orderId": "000017273",
7+
"paymentDate": "21-10-2024 15:41:00",
8+
"procDate": "20241021",
9+
"reference": "007875810",
10+
"requestId": "wIh3HzFByfmj75Adl98x",
11+
"subEntity": "XXX-000000",
12+
"terminal": "5-0000000000-CAIXA GERAL DE "
13+
}

0 commit comments

Comments
 (0)