Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/stripe/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.env*
!.env.example
**/*.log
coverage
dist
dist-ssr
node_modules
19 changes: 19 additions & 0 deletions packages/stripe/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import reactConfig from "@prefabs.tech/eslint-config/react.js";

export default [
...reactConfig,
{
rules: {
"unicorn/filename-case": [
"error",
{
cases: {
camelCase: true,
kebabCase: true,
pascalCase: true,
},
},
],
},
},
];
79 changes: 79 additions & 0 deletions packages/stripe/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
{
"name": "@prefabs.tech/react-stripe",
"version": "0.72.1",
"description": "React Stripe Plugin",
"type": "module",
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/PrefabsTechReactStripe.es.js",
"require": "./dist/PrefabsTechReactStripe.umd.js"
},
"./dist/PrefabsTechReactStripe.css": "./dist/react-stripe.css"
},
"main": "./dist/PrefabsTechReactStripe.umd.js",
"module": "./dist/PrefabsTechReactStripe.es.js",
"types": "./dist/src/index.d.ts",
"files": [
"dist"
],
"scripts": {
"build": "vite build && tsc --emitDeclarationOnly",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"snapshot:update": "vitest --environment jsdom run --update --passWithNoTests",
"sort-package": "npx sort-package-json",
"stylelint": "stylelint \"src/**/*.{css}\" --allow-empty-input",
"stylelint:fix": "stylelint \"src/**/*.{css}\" --fix --allow-empty-input",
"test": "pnpm build && vitest --environment jsdom run --coverage --passWithNoTests",
"test:component": "vitest --environment jsdom run component/ --passWithNoTests",
"test:snapshot": "vitest --environment jsdom run snapshot/ --passWithNoTests",
"test:unit": "vitest --environment jsdom run unit/ --passWithNoTests",
"test:watch": "vitest --environment jsdom",
"typecheck": "tsc --noEmit -p tsconfig.vitest.json --composite false"
},
"dependencies": {},
"devDependencies": {
"@prefabs.tech/eslint-config": "0.7.0",
"@prefabs.tech/react-config": "0.72.1",
"@prefabs.tech/react-i18n": "0.72.1",
"@prefabs.tech/react-ui": "0.72.1",
"@prefabs.tech/stylelint-config": "0.7.0",
"@prefabs.tech/tsconfig": "0.7.0",
"@testing-library/dom": "10.4.1",
"@testing-library/react": "16.3.2",
"@testing-library/user-event": "14.6.1",
"@types/jsdom": "21.1.7",
"@types/node": "25.6.0",
"@types/react": "18.3.28",
"@types/react-dom": "18.3.7",
"@vitejs/plugin-react": "5.2.0",
"@vitest/coverage-v8": "3.2.4",
"axios": "1.16.0",
"eslint": "9.39.4",
"jsdom": "27.4.0",
"prettier": "3.8.3",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-router-dom": "6.30.3",
"stylelint": "17.10.0",
"stylelint-config-standard": "40.0.0",
"stylelint-order": "8.1.1",
"typescript": "5.9.3",
"vite": "7.3.2",
"vitest": "3.2.4"
},
"peerDependencies": {
"@prefabs.tech/react-config": "0.72.1",
"@prefabs.tech/react-i18n": "0.72.1",
"@prefabs.tech/react-ui": "0.72.1",
"axios": "1.16.0",
"react": ">=18.3",
"react-dom": ">=18.3",
"react-router-dom": ">=6.30"
},
"engines": {
"node": ">=18",
"pnpm": ">=9"
}
}
14 changes: 14 additions & 0 deletions packages/stripe/src/api/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios from "axios";

const client = (baseURL: string) => {
return axios.create({
baseURL: baseURL,
headers: {
post: {
"Content-Type": "application/json",
},
},
});
};

export default client;
41 changes: 41 additions & 0 deletions packages/stripe/src/api/payment/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type {
CheckoutSessionPayload,
PrefabsTechReactStripeConfig,
} from "../../types";

import { API_PATH_CHECKOUT_SESSION, API_PATH_STATUS } from "../../constants";
import client from "../axios";

export const checkoutSession = async (
payload: CheckoutSessionPayload,
apiBaseUrl: string,
config?: PrefabsTechReactStripeConfig,
) => {
const path = config?.apiRoutes?.checkoutSession || API_PATH_CHECKOUT_SESSION;

const response = await client(apiBaseUrl).post(path, payload);

if ("error" in response.data) {
throw new Error(response.data);
}

const redirectUrl = response.data.url as string;
window.location.href = redirectUrl;

return response.data;
};

export const getStatus = async (
apiBaseUrl: string,
config?: PrefabsTechReactStripeConfig,
) => {
const path = config?.apiRoutes?.status || API_PATH_STATUS;

const response = await client(apiBaseUrl).get(path);

if ("error" in response.data) {
throw new Error(response.data);
}

return response.data;
};
98 changes: 98 additions & 0 deletions packages/stripe/src/assets/css/cancelled-page.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
.cancelled-page .card {
animation: fadeInUp 0.6s ease-out;
display: flex;
flex-direction: column;
gap: 1.5rem;
max-width: 30rem;
padding: 2rem 1.5rem;
text-align: center;
width: 100%;
}

.cancelled-page .card > .card-body {
display: flex;
flex-direction: column;
gap: 1rem;
min-height: 25rem;
}

.cancelled-page .crossmark {
margin: 0 auto 0.5rem;
stroke-width: 2;
width: 5rem;
}

.cancelled-page .crossmark-circle {
animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
stroke: #f44336;
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
}

.cancelled-page .crossmark-line {
animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.6s forwards;
stroke: var(--dz-danger-color, #dc3545);
stroke-dasharray: 28;
stroke-dashoffset: 28;
stroke-linecap: round;
stroke-width: 3;
transform-origin: 50% 50%;
}

.cancelled-page h1.title {
color: var(--dz-secondary-color, #475569);
font-size: 1.5rem;
font-weight: 700;
margin-block: 1rem;
}

.cancelled-page .message {
color: var(--dz-secondary-color, #475569);;
display: flex;
flex-direction: column;
font-size: 1rem;
gap: 0.5rem;
line-height: 1.5;
margin-block: auto;
}

.cancelled-page .message p {
margin: 0;
}

.cancelled-page button {
min-width: 12rem;
}

@keyframes stroke {
100% {
stroke-dashoffset: 0;
}
}

@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}

to {
opacity: 1;
transform: translateY(0);
}
}

@media (width >= 576px) {
.cancelled-page .card {
padding: 3rem 2rem;
}

.cancelled-page .crossmark {
width: 7rem;
}

.cancelled-page h1.title {
font-size: 2rem;
}
}
109 changes: 109 additions & 0 deletions packages/stripe/src/assets/css/success-page.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
.success-page .card {
animation: fadeInUp 0.6s ease-out;
display: flex;
flex-direction: column;
gap: 1.5rem;
max-width: 30rem;
padding: 2rem 1.5rem;
text-align: center;
width: 100%;
}

.success-page .card > .card-body {
display: flex;
flex-direction: column;
gap: 1rem;
min-height: 25rem;
}

.success-page .checkmark {
margin: 0 auto 0.5rem;
stroke-width: 2;
width: 5rem;
}

.success-page .checkmark-circle {
animation: stroke 0.6s cubic-bezier(0.65, 0, 0.45, 1) forwards;
stroke: var(--dz-success-color, #22c55e);
stroke-dasharray: 166;
stroke-dashoffset: 166;
stroke-width: 2;
}

.success-page .checkmark-check {
animation: stroke 0.3s cubic-bezier(0.65, 0, 0.45, 1) 0.6s forwards;
stroke: var(--dz-success-color, #22c55e);
stroke-dasharray: 48;
stroke-dashoffset: 48;
stroke-linecap: round;
stroke-width: 3;
transform-origin: 50% 50%;
}

.success-page h1.title {
color: var(--dz-secondary-color, #475569);;
font-size: 1.5rem;
font-weight: 700;
margin-block: 1rem;
}

.success-page p.subtitle {
color: #4caf50;
font-size: 1.125rem;
font-weight: 600;
margin: 0;
}

.success-page .message {
color: #666;
display: flex;
flex-direction: column;
font-size: 1rem;
gap: 0.5rem;
line-height: 1.5;
margin-block: auto;
}

.success-page .message p {
margin: 0;
}

.success-page button {
min-width: 12rem;
}

@keyframes stroke {
100% {
stroke-dashoffset: 0;
}
}

@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}

to {
opacity: 1;
transform: translateY(0);
}
}

@media (width >= 576px) {
.success-page .card {
padding: 3rem 2rem;
}

.success-page .checkmark {
width: 7rem;
}

.success-page h1.title {
font-size: 2rem;
}

.success-page p.subtitle {
font-size: 1.25rem;
}
}
Loading
Loading