Skip to content

Commit 286b5eb

Browse files
authored
Merge pull request #17 from lambda-curry/mohsen/360t-167-move-plugin-code-from-monorepo-packages-into-its-own-package
2 parents 2ed744e + bf29513 commit 286b5eb

File tree

26 files changed

+2928
-7
lines changed

26 files changed

+2928
-7
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,5 @@ build
2929

3030
.yalc
3131
yalc.lock
32+
33+
plugins/**/node_modules

plugins/braintree-payment/README.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# Braintree Payment Provider for Medusa
2+
3+
This plugin integrates Braintree as a payment provider for your Medusa store. It allows you to process payments, handle 3D Secure authentication, and manage payment methods seamlessly.
4+
5+
## Quick Start
6+
7+
1. **Install the plugin:**
8+
```bash
9+
npm install @lambdacurry/medusa-payment-braintree
10+
```
11+
2. **Set the required environment variables** in your `.env` file (see below).
12+
3. **Add the provider** to your `medusa-config.js` or `config.ts` (see below).
13+
4. **Add the required custom fields** in your Braintree dashboard (see below).
14+
5. **Restart your Medusa server.**
15+
16+
## Features
17+
18+
- Secure payment processing with Braintree.
19+
- Support for 3D Secure authentication.
20+
- Webhook handling for payment updates.
21+
- Save payment methods for future transactions.
22+
23+
## Installation
24+
25+
Install the plugin in your Medusa project:
26+
27+
```bash
28+
npm install @lambdacurry/medusa-payment-braintree
29+
```
30+
31+
## Configuration
32+
33+
### Environment Variables
34+
35+
Set the following environment variables in your `.env` file:
36+
37+
```env
38+
BRAINTREE_PUBLIC_KEY=<your_public_key>
39+
BRAINTREE_MERCHANT_ID=<your_merchant_id>
40+
BRAINTREE_PRIVATE_KEY=<your_private_key>
41+
BRAINTREE_WEBHOOK_SECRET=<your_webhook_secret>
42+
BRAINTREE_ENVIRONMENT=sandbox|development|production|qa
43+
BRAINTREE_ENABLE_3D_SECURE=true|false
44+
```
45+
46+
- `BRAINTREE_PUBLIC_KEY`: Your Braintree public key.
47+
- `BRAINTREE_MERCHANT_ID`: Your Braintree merchant ID.
48+
- `BRAINTREE_PRIVATE_KEY`: Your Braintree private key.
49+
- `BRAINTREE_WEBHOOK_SECRET`: Secret for validating Braintree webhooks.
50+
- `BRAINTREE_ENVIRONMENT`: One of `sandbox`, `development`, `production`, or `qa`.
51+
- `BRAINTREE_ENABLE_3D_SECURE`: Set to `true` to enable 3D Secure authentication, otherwise `false`.
52+
53+
### Medusa Configuration
54+
55+
Add the following configuration to the `payment` section of your `medusa-config.js` or `config.ts` file:
56+
57+
```javascript
58+
{
59+
resolve: '@lambdacurry/medusa-payment-braintree/providers/payment-braintree',
60+
id: 'braintree',
61+
options: {
62+
environment: process.env.BRAINTREE_ENVIRONMENT || (process.env.NODE_ENV !== 'production' ? 'sandbox' : 'production'),
63+
merchantId: process.env.BRAINTREE_MERCHANT_ID,
64+
publicKey: process.env.BRAINTREE_PUBLIC_KEY,
65+
privateKey: process.env.BRAINTREE_PRIVATE_KEY,
66+
webhookSecret: process.env.BRAINTREE_WEBHOOK_SECRET,
67+
enable3DSecure: process.env.BRAINTREE_ENABLE_3D_SECURE === 'true',
68+
savePaymentMethod: true, // Save payment methods for future use
69+
autoCapture: true, // Automatically capture payments
70+
}
71+
}
72+
```
73+
74+
#### Options
75+
76+
- **merchantId**: Your Braintree Merchant ID.
77+
- **publicKey**: Your Braintree Public Key.
78+
- **privateKey**: Your Braintree Private Key.
79+
- **webhookSecret**: Secret for validating Braintree webhooks.
80+
- **enable3DSecure**: Enable 3D Secure authentication (`true` or `false`).
81+
- **savePaymentMethod**: Save payment methods for future use (default: `true`).
82+
- **autoCapture**: Automatically capture payments (default: `true`).
83+
84+
> **Note:**
85+
> - `autoCapture`: If set to `true`, payments are captured automatically after authorization.
86+
> - `savePaymentMethod`: If set to `true`, customer payment methods are saved for future use.
87+
88+
### 3D Secure Setup
89+
90+
If you enable 3D Secure (`BRAINTREE_ENABLE_3D_SECURE=true`), you may need to make additional changes on your storefront to support 3D Secure flows. Refer to the [Braintree 3D Secure documentation](https://developer.paypal.com/braintree/docs/guides/3d-secure/overview/) for more details.
91+
92+
### Webhook Setup
93+
94+
To handle payment updates from Braintree, you need to configure webhooks:
95+
96+
1. In your Braintree dashboard, go to **Settings > Webhooks**.
97+
2. Add a new webhook and set the URL to your Medusa server's webhook endpoint (e.g., `https://your-medusa-server.com/webhooks/braintree`).
98+
3. Use the value of `BRAINTREE_WEBHOOK_SECRET` as the secret for validating incoming webhooks.
99+
4. Make sure your Medusa server is configured to handle Braintree webhook events.
100+
101+
For more information, see the [Braintree Webhooks documentation](https://developer.paypal.com/braintree/docs/guides/webhooks/overview).
102+
103+
### Adding Custom Fields in the Braintree Dashboard
104+
105+
To ensure proper integration with Medusa, you need to add the following custom fields in your Braintree dashboard:
106+
107+
1. **Navigate to:**
108+
`Account Settings``Transactions``Custom Fields`
109+
110+
2. **Add each custom field:**
111+
- Click the **Options** button.
112+
- Click the **Add** button.
113+
- Enter the details for each field as shown below:
114+
115+
| Field Name | API Name | Description | Options |
116+
|--------------------------|-----------------------------|---------------------|---------------------|
117+
| Medusa Payment Session Id | `medusa_payment_session_id` | Medusa Session Id | Store and Pass back |
118+
| Cart Id | `cart_id` | Cart Id | Store and Pass back |
119+
| Customer Id | `customer_id` | Customer Id | Store and Pass back |
120+
121+
> **Note:**
122+
> - The **API Name** must be in lowercase.
123+
> - Set the **Options** to "Store and Pass back" for each field.
124+
125+
## License
126+
127+
This plugin is licensed under the [MIT License](LICENSE).
128+
129+
For more information, visit the [Braintree Documentation](https://developer.paypal.com/braintree/docs).
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
{
2+
"name": "@lambdacurry/medusa-payment-braintree",
3+
"version": "0.0.5",
4+
"description": "Braintree plugin for Medusa",
5+
"author": "Lambda Curry (https://lambdacurry.dev)",
6+
"license": "MIT",
7+
"repository": {
8+
"type": "git",
9+
"url": "git+https://github.com/lambda-curry/medusa-plugins.git"
10+
},
11+
"homepage": "https://github.com/lambda-curry/medusa-plugins/tree/main/plugins/braintree-payment",
12+
"files": [
13+
".medusa/server"
14+
],
15+
"exports": {
16+
"./package.json": "./package.json",
17+
"./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
18+
"./providers/*": "./.medusa/server/src/providers/*/src/index.js",
19+
"./*": "./.medusa/server/src/*.js"
20+
},
21+
"keywords": [
22+
"medusa",
23+
"plugin",
24+
"braintree",
25+
"medusa-plugin-integration",
26+
"medusa-v2",
27+
"medusa-plugin-braintree",
28+
"medusa-plugin",
29+
"medusa-plugin-payment",
30+
"lambdacurry"
31+
],
32+
"devDependencies": {
33+
"@medusajs/admin-sdk": "2.8.2",
34+
"@medusajs/cli": "2.8.2",
35+
"@medusajs/framework": "2.8.2",
36+
"@medusajs/icons": "2.8.2",
37+
"@medusajs/medusa": "2.8.2",
38+
"@medusajs/test-utils": "2.8.2",
39+
"@medusajs/ui": "4.0.3",
40+
"@swc/core": "1.5.7",
41+
"@types/braintree": "^3.3.14"
42+
},
43+
"scripts": {
44+
"build": "npx medusa plugin:build",
45+
"plugin:dev": "npx medusa plugin:develop",
46+
"prepublishOnly": "npx medusa plugin:build"
47+
},
48+
"peerDependencies": {
49+
"@medusajs/admin-sdk": "2.8.2",
50+
"@medusajs/cli": "2.8.2",
51+
"@medusajs/framework": "2.8.2",
52+
"@medusajs/icons": "2.8.2",
53+
"@medusajs/medusa": "2.8.2",
54+
"@medusajs/test-utils": "2.8.2",
55+
"@medusajs/ui": "4.0.3"
56+
},
57+
"engines": {
58+
"node": ">=20"
59+
},
60+
"dependencies": {
61+
"braintree": "^3.30.0"
62+
}
63+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Admin Customizations
2+
3+
You can extend the Medusa Admin to add widgets and new pages. Your customizations interact with API routes to provide merchants with custom functionalities.
4+
5+
## Example: Create a Widget
6+
7+
A widget is a React component that can be injected into an existing page in the admin dashboard.
8+
9+
For example, create the file `src/admin/widgets/product-widget.tsx` with the following content:
10+
11+
```tsx title="src/admin/widgets/product-widget.tsx"
12+
import { defineWidgetConfig } from "@medusajs/admin-sdk"
13+
14+
// The widget
15+
const ProductWidget = () => {
16+
return (
17+
<div>
18+
<h2>Product Widget</h2>
19+
</div>
20+
)
21+
}
22+
23+
// The widget's configurations
24+
export const config = defineWidgetConfig({
25+
zone: "product.details.after",
26+
})
27+
28+
export default ProductWidget
29+
```
30+
31+
This inserts a widget with the text “Product Widget” at the end of a product’s details page.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES2020",
4+
"useDefineForClassFields": true,
5+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
6+
"module": "ESNext",
7+
"skipLibCheck": true,
8+
9+
/* Bundler mode */
10+
"moduleResolution": "bundler",
11+
"allowImportingTsExtensions": true,
12+
"resolveJsonModule": true,
13+
"isolatedModules": true,
14+
"noEmit": true,
15+
"jsx": "react-jsx",
16+
17+
/* Linting */
18+
"strict": true,
19+
"noUnusedLocals": true,
20+
"noUnusedParameters": true,
21+
"noFallthroughCasesInSwitch": true
22+
},
23+
"include": ["."]
24+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="vite/client" />
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Custom API Routes
2+
3+
An API Route is a REST API endpoint.
4+
5+
An API Route is created in a TypeScript or JavaScript file under the `/src/api` directory of your Medusa application. The file’s name must be `route.ts` or `route.js`.
6+
7+
For example, to create a `GET` API Route at `/store/hello-world`, create the file `src/api/store/hello-world/route.ts` with the following content:
8+
9+
```ts
10+
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
11+
12+
export async function GET(req: MedusaRequest, res: MedusaResponse) {
13+
res.json({
14+
message: "Hello world!",
15+
});
16+
}
17+
```
18+
19+
## Supported HTTP methods
20+
21+
The file based routing supports the following HTTP methods:
22+
23+
- GET
24+
- POST
25+
- PUT
26+
- PATCH
27+
- DELETE
28+
- OPTIONS
29+
- HEAD
30+
31+
You can define a handler for each of these methods by exporting a function with the name of the method in the paths `route.ts` file.
32+
33+
For example:
34+
35+
```ts
36+
import type { MedusaRequest, MedusaResponse } from "@medusajs/framework/http";
37+
38+
export async function GET(req: MedusaRequest, res: MedusaResponse) {
39+
// Handle GET requests
40+
}
41+
42+
export async function POST(req: MedusaRequest, res: MedusaResponse) {
43+
// Handle POST requests
44+
}
45+
46+
export async function PUT(req: MedusaRequest, res: MedusaResponse) {
47+
// Handle PUT requests
48+
}
49+
```
50+
51+
## Parameters
52+
53+
To create an API route that accepts a path parameter, create a directory within the route's path whose name is of the format `[param]`.
54+
55+
For example, if you want to define a route that takes a `productId` parameter, you can do so by creating a file called `/api/products/[productId]/route.ts`:
56+
57+
```ts
58+
import type {
59+
MedusaRequest,
60+
MedusaResponse,
61+
} from "@medusajs/framework/http"
62+
63+
export async function GET(req: MedusaRequest, res: MedusaResponse) {
64+
const { productId } = req.params;
65+
66+
res.json({
67+
message: `You're looking for product ${productId}`
68+
})
69+
}
70+
```
71+
72+
To create an API route that accepts multiple path parameters, create within the file's path multiple directories whose names are of the format `[param]`.
73+
74+
For example, if you want to define a route that takes both a `productId` and a `variantId` parameter, you can do so by creating a file called `/api/products/[productId]/variants/[variantId]/route.ts`.
75+
76+
## Using the container
77+
78+
The Medusa container is available on `req.scope`. Use it to access modules' main services and other registered resources:
79+
80+
```ts
81+
import type {
82+
MedusaRequest,
83+
MedusaResponse,
84+
} from "@medusajs/framework/http"
85+
86+
export const GET = async (
87+
req: MedusaRequest,
88+
res: MedusaResponse
89+
) => {
90+
const productModuleService = req.scope.resolve("product")
91+
92+
const [, count] = await productModuleService.listAndCount()
93+
94+
res.json({
95+
count,
96+
})
97+
}
98+
```
99+
100+
## Middleware
101+
102+
You can apply middleware to your routes by creating a file called `/api/middlewares.ts`. This file must export a configuration object with what middleware you want to apply to which routes.
103+
104+
For example, if you want to apply a custom middleware function to the `/store/custom` route, you can do so by adding the following to your `/api/middlewares.ts` file:
105+
106+
```ts
107+
import { defineMiddlewares } from "@medusajs/framework/http"
108+
import type {
109+
MedusaRequest,
110+
MedusaResponse,
111+
MedusaNextFunction,
112+
} from "@medusajs/framework/http";
113+
114+
async function logger(
115+
req: MedusaRequest,
116+
res: MedusaResponse,
117+
next: MedusaNextFunction
118+
) {
119+
console.log("Request received");
120+
next();
121+
}
122+
123+
export default defineMiddlewares({
124+
routes: [
125+
{
126+
matcher: "/store/custom",
127+
middlewares: [logger],
128+
},
129+
],
130+
})
131+
```
132+
133+
The `matcher` property can be either a string or a regular expression. The `middlewares` property accepts an array of middleware functions.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
### place holder for store routes

0 commit comments

Comments
 (0)