@a-tech.jo/atech_payment 1.0.5 → 1.0.6
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/example/hyperpay/requests/createOrder.json +37 -0
- package/example/hyperpay/use.js +0 -0
- package/package.json +1 -1
- package/src/hyperpay/hyperpayOrder.js +99 -0
- package/src/paypal/buttonWrapper.js +76 -0
- package/src/paypal/paypalOrder.js +32 -0
- package/src/shared/config.js +12 -0
- package/src/shared/paypalService.js +16 -0
- package/src/shared/requests/backendConnector.js +24 -0
- package/src/shared/requests/hyperpayConnector.js +57 -0
- package/src/shared/requests/request.js +90 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"entityId":"8a8294174d0595bb014d05d82e5b01d2",
|
|
3
|
+
"amount":"0.00",
|
|
4
|
+
"paymentType":"PA",
|
|
5
|
+
"createRegistration":"true",
|
|
6
|
+
"currency":"EUR",
|
|
7
|
+
"testMode":"EXTERNAL",
|
|
8
|
+
"paymentBrand":"VISA",
|
|
9
|
+
"card.number":"4242426505984705",
|
|
10
|
+
"card.holder":"John Smith",
|
|
11
|
+
"card.expiryMonth":"12",
|
|
12
|
+
"card.expiryYear":"2026",
|
|
13
|
+
"card.cvv":"123",
|
|
14
|
+
"customer.email":"john.smith@gmail.com",
|
|
15
|
+
"customer.givenName":"Smith",
|
|
16
|
+
"customer.ip":"192.168.0.0",
|
|
17
|
+
"customer.surname":"John",
|
|
18
|
+
"customer.language":"DE",
|
|
19
|
+
"billing.city":"MyCity",
|
|
20
|
+
"billing.country":"DE",
|
|
21
|
+
"billing.postcode":"712121",
|
|
22
|
+
"billing.state":"DE",
|
|
23
|
+
"billing.street1":"MyStreet",
|
|
24
|
+
"standingInstruction.type":"RECURRING",
|
|
25
|
+
"standingInstruction.mode":"INITIAL",
|
|
26
|
+
"standingInstruction.source":"CIT",
|
|
27
|
+
"standingInstruction.recurringType":"SUBSCRIPTION",
|
|
28
|
+
"threeDSecure.eci":"05",
|
|
29
|
+
"threeDSecure.authenticationStatus":"Y",
|
|
30
|
+
"threeDSecure.version":"2.2.0",
|
|
31
|
+
"threeDSecure.dsTransactionId":"c75f23af-9454-43f6-ba17-130ed529507e",
|
|
32
|
+
"threeDSecure.acsTransactionId":"2c42c553-176f-4f08-af6c-f9364ecbd0e8",
|
|
33
|
+
"threeDSecure.verificationId":"MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=",
|
|
34
|
+
"threeDSecure.amount":"19.99",
|
|
35
|
+
"threeDSecure.currency":"EUR",
|
|
36
|
+
"threeDSecure.flow":"challenge"
|
|
37
|
+
}
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import hyperpayConnector from "../shared/requests/hyperpayConnector.js";
|
|
3
|
+
|
|
4
|
+
const HyperpayOrder = ({ redirectUrl, order, env }) => {
|
|
5
|
+
const [error, setError] = useState(null);
|
|
6
|
+
const [checkoutId, setCheckoutId] = useState(null);
|
|
7
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
8
|
+
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (order) {
|
|
11
|
+
initiateOrder();
|
|
12
|
+
}
|
|
13
|
+
}, [order]);
|
|
14
|
+
|
|
15
|
+
const initiateOrder = async () => {
|
|
16
|
+
try {
|
|
17
|
+
if (!order) {
|
|
18
|
+
setError("Data must be provided");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
setIsLoading(true);
|
|
22
|
+
const result = await hyperpayConnector.createHyperpayOrder(order, env);
|
|
23
|
+
setIsLoading(false);
|
|
24
|
+
|
|
25
|
+
if (result?.error) {
|
|
26
|
+
setError(result.error);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
setCheckoutId(result?.id);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.error("err", err);
|
|
33
|
+
setError("An unexpected error occurred.");
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const checkout = async ( ) => {
|
|
38
|
+
try {
|
|
39
|
+
if (!checkoutId) {
|
|
40
|
+
setError("Checkout ID must be provided");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
setIsLoading(true);
|
|
44
|
+
const result = await hyperpayConnector.getOrderStatus(checkoutId, env);
|
|
45
|
+
setIsLoading(false);
|
|
46
|
+
|
|
47
|
+
if (result?.error) {
|
|
48
|
+
setError(result.error);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return result;
|
|
53
|
+
} catch (err) {
|
|
54
|
+
console.error("err", err);
|
|
55
|
+
setError("An unexpected error occurred.");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (checkoutId) {
|
|
61
|
+
const script = document.createElement("script");
|
|
62
|
+
script.src = `https://eu-test.oppwa.com/v1/paymentWidgets.js?checkoutId=${checkoutId}`;
|
|
63
|
+
script.async = true;
|
|
64
|
+
script.crossOrigin = "anonymous";
|
|
65
|
+
document.body.appendChild(script);
|
|
66
|
+
|
|
67
|
+
return () => {
|
|
68
|
+
document.body.removeChild(script);
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}, [checkoutId]);
|
|
72
|
+
|
|
73
|
+
if (error) {
|
|
74
|
+
return <p>Error: {error}</p>;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
if (isLoading) {
|
|
79
|
+
return <p>Loading...</p>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (checkoutId) {
|
|
83
|
+
return (
|
|
84
|
+
<form
|
|
85
|
+
action={redirectUrl}
|
|
86
|
+
className="paymentWidgets"
|
|
87
|
+
data-brands="VISA MASTER AMEX"
|
|
88
|
+
></form>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div>
|
|
94
|
+
<p>No order</p>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export default HyperpayOrder;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { PayPalButtons, usePayPalScriptReducer } from "@paypal/react-paypal-js";
|
|
3
|
+
import backendConnector from "../shared/requests/backendConnector.js";
|
|
4
|
+
|
|
5
|
+
const Spinner = () => <div className="spinner">Processing payment...</div>;
|
|
6
|
+
|
|
7
|
+
const ButtonWrapper = ({
|
|
8
|
+
order,
|
|
9
|
+
onChange = () => {},
|
|
10
|
+
onStatusChange = () => {},
|
|
11
|
+
env,
|
|
12
|
+
}) => {
|
|
13
|
+
if (env !== "production" && env !== "development") {
|
|
14
|
+
return <div>Invalid Env</div>;
|
|
15
|
+
}
|
|
16
|
+
const [{ isPending }] = usePayPalScriptReducer();
|
|
17
|
+
|
|
18
|
+
const createOrderOrSubscription = async () => {
|
|
19
|
+
try {
|
|
20
|
+
const response = await backendConnector.createPaypalOrder(order, env);
|
|
21
|
+
onChange({ event: "createOrder", data: response });
|
|
22
|
+
return response.id;
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error("Error creating PayPal transaction:", error);
|
|
25
|
+
throw new Error("Transaction creation failed");
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const handleApproval = async (data, actions) => {
|
|
30
|
+
try {
|
|
31
|
+
console.log(data);
|
|
32
|
+
const captureData = {
|
|
33
|
+
orderId: data?.orderID || undefined,
|
|
34
|
+
subscriptionId: data?.subscriptionID || data?.id,
|
|
35
|
+
type: order.type,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
await backendConnector.approveOrder(captureData, env);
|
|
39
|
+
if (order.type == "order") {
|
|
40
|
+
return actions.order.capture().then(function (details) {
|
|
41
|
+
onStatusChange(true);
|
|
42
|
+
onChange({ event: "approveOrder", data: data });
|
|
43
|
+
|
|
44
|
+
console.log(
|
|
45
|
+
"Transaction completed by " + details.payer.name.given_name
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
onStatusChange(true);
|
|
50
|
+
onChange({ event: "approveOrder", data: data });
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error("Error capturing PayPal transaction:", error);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<>
|
|
58
|
+
{isPending ? <Spinner /> : null}
|
|
59
|
+
<PayPalButtons
|
|
60
|
+
style={{ layout: "vertical" }}
|
|
61
|
+
disabled={false}
|
|
62
|
+
fundingSource={undefined}
|
|
63
|
+
createOrder={
|
|
64
|
+
order.type === "order" ? createOrderOrSubscription : undefined
|
|
65
|
+
}
|
|
66
|
+
createSubscription={
|
|
67
|
+
order.type === "subscription" ? createOrderOrSubscription : undefined
|
|
68
|
+
}
|
|
69
|
+
onError={(err) => console.log(err)}
|
|
70
|
+
onApprove={handleApproval}
|
|
71
|
+
/>
|
|
72
|
+
</>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default ButtonWrapper;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { PayPalScriptProvider } from "@paypal/react-paypal-js";
|
|
3
|
+
import ButtonWrapper from "./buttonWrapper.js";
|
|
4
|
+
|
|
5
|
+
const PaypalOrder = ({
|
|
6
|
+
currency = "USD",
|
|
7
|
+
clientId = "test",
|
|
8
|
+
order = {},
|
|
9
|
+
onChange = () => {},
|
|
10
|
+
onStatusChange = () => {},
|
|
11
|
+
env,
|
|
12
|
+
}) => {
|
|
13
|
+
const initialOptions = {
|
|
14
|
+
clientId: clientId,
|
|
15
|
+
currency: currency,
|
|
16
|
+
vault: order.type === "subscription",
|
|
17
|
+
};
|
|
18
|
+
return (
|
|
19
|
+
<div style={{ maxWidth: "750px", minHeight: "200px" }}>
|
|
20
|
+
<PayPalScriptProvider options={initialOptions}>
|
|
21
|
+
<ButtonWrapper
|
|
22
|
+
order={order}
|
|
23
|
+
onChange={onChange}
|
|
24
|
+
onStatusChange={onStatusChange}
|
|
25
|
+
env={env}
|
|
26
|
+
/>
|
|
27
|
+
</PayPalScriptProvider>
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default PaypalOrder;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const config = {
|
|
2
|
+
development: {
|
|
3
|
+
BACKEND_BASE_URL: "http://localhost:5000/api",
|
|
4
|
+
HYPERPAY_BASE_URL: "https://eu-test.oppwa.com/",
|
|
5
|
+
},
|
|
6
|
+
production: {
|
|
7
|
+
BACKEND_BASE_URL: "http://prod:5000/api",
|
|
8
|
+
HYPERPAY_BASE_URL: "https://eu-prod.oppwa.com/",
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default config;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Services
|
|
2
|
+
import backendConnector from "./requests/backendConnector";
|
|
3
|
+
|
|
4
|
+
class PaypalService {
|
|
5
|
+
async createOrder(data) {
|
|
6
|
+
const result = await backendConnector.createPaypalOrder(data);
|
|
7
|
+
if (result?.id) return result?.id;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
async onApprove(data) {
|
|
11
|
+
const result = await backendConnector.approveOrder(data);
|
|
12
|
+
return result;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default new PaypalService();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Services
|
|
2
|
+
import request from "./request.js";
|
|
3
|
+
|
|
4
|
+
class BackendConnector {
|
|
5
|
+
async createPaypalOrder(data, env) {
|
|
6
|
+
const requestConfig = {
|
|
7
|
+
url: "/paypal/orders/create-order",
|
|
8
|
+
data,
|
|
9
|
+
};
|
|
10
|
+
const result = await request.post(requestConfig, env);
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async approveOrder(data, env) {
|
|
15
|
+
const requestConfig = {
|
|
16
|
+
url: "/paypal/orders/capture-order",
|
|
17
|
+
data,
|
|
18
|
+
};
|
|
19
|
+
const result = await request.post(requestConfig, env);
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default new BackendConnector();
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Services
|
|
2
|
+
import config from "../config.js";
|
|
3
|
+
import request from "./request.js";
|
|
4
|
+
|
|
5
|
+
class HyperpayConnector {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.BASEURL = config.production.HYPERPAY_BASE_URL;
|
|
8
|
+
this.DEV_BASEURL = config.development.HYPERPAY_BASE_URL;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
defaultHeaders = (data) => {
|
|
12
|
+
const headers = {
|
|
13
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
14
|
+
"Content-Length": data?.length,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return headers;
|
|
18
|
+
};
|
|
19
|
+
async createHyperpayOrder(data, env) {
|
|
20
|
+
const headers = this.defaultHeaders();
|
|
21
|
+
const url = "/hyperpay/orders/create-order";
|
|
22
|
+
const requestConfig = {
|
|
23
|
+
url: url,
|
|
24
|
+
// baseUrl: env === "development" ? this.DEV_BASEURL : this.BASEURL,
|
|
25
|
+
data,
|
|
26
|
+
headers: headers,
|
|
27
|
+
};
|
|
28
|
+
console.log("requestConfig", requestConfig);
|
|
29
|
+
const result = await request.post(requestConfig, env);
|
|
30
|
+
console.log("result", result);
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async getOrderStatus(checkoutId, env = "production") {
|
|
35
|
+
const headers = this.defaultHeaders();
|
|
36
|
+
const requestConfig = {
|
|
37
|
+
url: `/hyperpay/orders/get-order/${checkoutId}`,
|
|
38
|
+
// baseUrl: env === "development" ? this.DEV_BASEURL : this.BASEURL,
|
|
39
|
+
headers,
|
|
40
|
+
};
|
|
41
|
+
const result = await request.get(requestConfig);
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async captureOrder(orderId, env = "production") {
|
|
46
|
+
const headers = this.defaultHeaders();
|
|
47
|
+
const requestConfig = {
|
|
48
|
+
url: `/hyperpay/orders/capture-order/${orderId}`,
|
|
49
|
+
// baseUrl: env === "development" ? this.DEV_BASEURL : this.BASEURL,
|
|
50
|
+
headers,
|
|
51
|
+
};
|
|
52
|
+
const result = await request.post(requestConfig);
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default new HyperpayConnector();
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
// CONFIG
|
|
3
|
+
import config from "../config.js";
|
|
4
|
+
|
|
5
|
+
class Request {
|
|
6
|
+
constructor() {}
|
|
7
|
+
|
|
8
|
+
async handleRequests(finalConfig, env) {
|
|
9
|
+
try {
|
|
10
|
+
axios.defaults.baseURL = config[env].BACKEND_BASE_URL;
|
|
11
|
+
const response = await axios.request(finalConfig);
|
|
12
|
+
|
|
13
|
+
return response.data;
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.log("err", err);
|
|
16
|
+
if (err.response) {
|
|
17
|
+
if (err.response.status === 401) {
|
|
18
|
+
return (window.location.href = "/login");
|
|
19
|
+
}
|
|
20
|
+
return err.response.data;
|
|
21
|
+
} else if (err.request) {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
message: "No response received, please try again later.",
|
|
25
|
+
};
|
|
26
|
+
} else {
|
|
27
|
+
|
|
28
|
+
return { success: false, message: "An unexpected error occurred." };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async post(config, env) {
|
|
34
|
+
const defaultConfig = {
|
|
35
|
+
method: "post",
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const finalConfig = {
|
|
39
|
+
...defaultConfig,
|
|
40
|
+
...config,
|
|
41
|
+
};
|
|
42
|
+
return await this.handleRequests(finalConfig, env);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async get(config = {}, env) {
|
|
46
|
+
const defaultConfig = {
|
|
47
|
+
method: "get",
|
|
48
|
+
};
|
|
49
|
+
const finalConfig = {
|
|
50
|
+
...defaultConfig,
|
|
51
|
+
...config,
|
|
52
|
+
};
|
|
53
|
+
return await this.handleRequests(finalConfig, env);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async put(config, env) {
|
|
57
|
+
const defaultConfig = {
|
|
58
|
+
method: "put",
|
|
59
|
+
};
|
|
60
|
+
const finalConfig = {
|
|
61
|
+
...defaultConfig,
|
|
62
|
+
...config,
|
|
63
|
+
};
|
|
64
|
+
return await this.handleRequests(finalConfig, env);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async patch(config, env) {
|
|
68
|
+
const defaultConfig = {
|
|
69
|
+
method: "patch",
|
|
70
|
+
};
|
|
71
|
+
const finalConfig = {
|
|
72
|
+
...defaultConfig,
|
|
73
|
+
...config,
|
|
74
|
+
};
|
|
75
|
+
return await this.handleRequests(finalConfig, env);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async delete(config, env) {
|
|
79
|
+
const defaultConfig = {
|
|
80
|
+
method: "delete",
|
|
81
|
+
};
|
|
82
|
+
const finalConfig = {
|
|
83
|
+
...defaultConfig,
|
|
84
|
+
...config,
|
|
85
|
+
};
|
|
86
|
+
return await this.handleRequests(finalConfig, env);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export default new Request();
|