Skip to content

Commit 33d4e61

Browse files
authored
Merge pull request #1055 from bavix/merchant-docs
Merchant docs
2 parents f37eedc + 015e9f3 commit 33d4e61

File tree

4 files changed

+272
-1
lines changed

4 files changed

+272
-1
lines changed

docs/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export default defineConfig({
9797
{ text: 'Gift', link: '/guide/purchases/gift' },
9898
{ text: 'Cart', link: '/guide/purchases/cart' },
9999
{ text: 'Commissions', link: '/guide/purchases/commissions' },
100+
{ text: 'Merchant Fee Deductible', link: '/guide/purchases/merchant-fee-deductible' },
100101
{ text: 'Customize receiving', link: '/guide/purchases/receiving' },
101102
],
102103
collapsed: false,

docs/guide/purchases/commissions.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,22 @@ $user->safePay($item); // failed, 100 (product) + 5 (minimal fee) = 105
169169
$user->balance; // 103
170170
```
171171

172+
## Alternative: Merchant Fee Deductible
173+
174+
By default, the `Taxable` interface adds fees to the customer's payment. If you want to deduct fees from the merchant's payout instead (so customers pay only the product price), you can use the `MerchantFeeDeductible` interface.
175+
176+
**With Taxable (default behavior):**
177+
- Product price: $100
178+
- Fee: 5%
179+
- Customer pays: $105 ($100 + $5 fee)
180+
- Merchant receives: $100
181+
182+
**With MerchantFeeDeductible:**
183+
- Product price: $100
184+
- Fee: 5%
185+
- Customer pays: $100
186+
- Merchant receives: $95 ($100 - $5 fee)
187+
188+
For more information, see the [Merchant Fee Deductible](/guide/purchases/merchant-fee-deductible) documentation.
189+
172190
It's simple!

docs/guide/purchases/gift.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ $item->balance; // 0
115115

116116
The first user buys the product and gives it.
117117

118-
> If the product uses the `Taxable` interface, then Santa will pay tax
118+
> If the product uses the `Taxable` interface, then Santa will pay tax.
119+
> If the product uses the `MerchantFeeDeductible` interface, the fee is deducted from the merchant's payout instead.
119120
120121
```php
121122
$first->gift($last, $item);
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# Merchant Fee Deductible
2+
3+
The `MerchantFeeDeductible` interface allows you to deduct fees from the merchant's payout instead of adding them to the customer's payment. This means customers pay only the listed product price, while merchants receive the product price minus the fee.
4+
5+
## How It Works
6+
7+
By default, when using the `Taxable` interface, fees are added to the customer's payment:
8+
9+
- **Product price:** $100
10+
- **Fee:** 5%
11+
- **Customer pays:** $105 ($100 + $5 fee)
12+
- **Merchant receives:** $100
13+
14+
When using `MerchantFeeDeductible`, fees are deducted from the merchant's payout:
15+
16+
- **Product price:** $100
17+
- **Fee:** 5%
18+
- **Customer pays:** $100
19+
- **Merchant receives:** $95 ($100 - $5 fee)
20+
21+
## User Model
22+
23+
Add the `CanPay` trait and `Customer` interface to your User model.
24+
25+
> The trait `CanPay` already inherits `HasWallet`, reuse will cause an error.
26+
27+
```php
28+
use Bavix\Wallet\Traits\CanPay;
29+
use Bavix\Wallet\Interfaces\Customer;
30+
31+
class User extends Model implements Customer
32+
{
33+
use CanPay;
34+
}
35+
```
36+
37+
## Item Model
38+
39+
Add the `HasWallet` trait and implement both `ProductInterface` (or `ProductLimitedInterface`) and `MerchantFeeDeductible` interfaces to your Item model.
40+
41+
The `MerchantFeeDeductible` interface extends `Taxable`, so you need to implement the `getFeePercent()` method.
42+
43+
```php
44+
use Bavix\Wallet\Traits\HasWallet;
45+
use Bavix\Wallet\Interfaces\Customer;
46+
use Bavix\Wallet\Interfaces\MerchantFeeDeductible;
47+
use Bavix\Wallet\Interfaces\ProductLimitedInterface;
48+
49+
class Item extends Model implements ProductLimitedInterface, MerchantFeeDeductible
50+
{
51+
use HasWallet;
52+
53+
public function canBuy(Customer $customer, int $quantity = 1, bool $force = false): bool
54+
{
55+
/**
56+
* If the service can be purchased once, then
57+
* return !$customer->paid($this);
58+
*/
59+
return true;
60+
}
61+
62+
public function getAmountProduct(Customer $customer): int|string
63+
{
64+
return 100;
65+
}
66+
67+
public function getMetaProduct(): ?array
68+
{
69+
return [
70+
'title' => $this->title,
71+
'description' => 'Purchase of Product #' . $this->id,
72+
];
73+
}
74+
75+
/**
76+
* Specify the percentage of the amount. For example, the product costs $100, the fee is 5%.
77+
* With MerchantFeeDeductible, customer pays $100, merchant receives $95.
78+
*
79+
* Minimum 0; Maximum 100
80+
*/
81+
public function getFeePercent(): float|int
82+
{
83+
return 5.0; // 5%
84+
}
85+
}
86+
```
87+
88+
## Payment Process
89+
90+
Find the user and check the balance.
91+
92+
```php
93+
$user = User::first();
94+
$user->balance; // 100
95+
```
96+
97+
Find the goods and check the cost.
98+
99+
```php
100+
$item = Item::first();
101+
$item->getAmountProduct($user); // 100
102+
```
103+
104+
The user can buy a product. With `MerchantFeeDeductible`, the customer only needs to pay the product price (no fee added).
105+
106+
```php
107+
$user->pay($item); // success, customer pays $100 (product price)
108+
$user->balance; // 0
109+
```
110+
111+
After payment:
112+
- Customer balance: $0 (paid $100)
113+
- Merchant balance: $95 (received $100 - $5 fee)
114+
- Transfer fee: $5
115+
116+
## Combining with MinimalTaxable and MaximalTaxable
117+
118+
You can combine `MerchantFeeDeductible` with `MinimalTaxable` or `MaximalTaxable` interfaces to set minimum or maximum fee limits.
119+
120+
```php
121+
use Bavix\Wallet\Traits\HasWallet;
122+
use Bavix\Wallet\Interfaces\Customer;
123+
use Bavix\Wallet\Interfaces\MerchantFeeDeductible;
124+
use Bavix\Wallet\Interfaces\MinimalTaxable;
125+
use Bavix\Wallet\Interfaces\ProductInterface;
126+
127+
class Item extends Model implements ProductInterface, MerchantFeeDeductible, MinimalTaxable
128+
{
129+
use HasWallet;
130+
131+
public function getAmountProduct(Customer $customer): int|string
132+
{
133+
return 100;
134+
}
135+
136+
public function getMetaProduct(): ?array
137+
{
138+
return [
139+
'title' => $this->title,
140+
'description' => 'Purchase of Product #' . $this->id,
141+
];
142+
}
143+
144+
public function getFeePercent(): float|int
145+
{
146+
return 0.03; // 3%
147+
}
148+
149+
public function getMinimalFee(): int|string
150+
{
151+
return 5; // 3%, minimum 5
152+
}
153+
}
154+
```
155+
156+
#### Example with Minimal Fee
157+
158+
Find the user and check the balance.
159+
160+
```php
161+
$user = User::first();
162+
$user->balance; // 100
163+
```
164+
165+
Find the goods and check the cost.
166+
167+
```php
168+
$item = Item::first();
169+
$item->getAmountProduct($user); // 100
170+
```
171+
172+
The user can buy a product. With `MerchantFeeDeductible` and `MinimalTaxable`:
173+
- Customer pays: $100 (product price, no fee added)
174+
- Merchant receives: $95 ($100 - $5 minimal fee)
175+
176+
```php
177+
$user->pay($item); // success, customer pays $100
178+
$user->balance; // 0
179+
```
180+
181+
## Gifts
182+
183+
The `MerchantFeeDeductible` interface also works with gift payments. When gifting a product, the customer pays only the product price, and the merchant receives the product price minus the fee.
184+
185+
```php
186+
$santa = User::first();
187+
$child = User::find(2);
188+
189+
$item = Item::first();
190+
$item->getAmountProduct($santa); // 100
191+
192+
// Santa deposits only the product price
193+
$santa->deposit(100);
194+
$santa->balance; // 100
195+
196+
// Gift the product
197+
$transfer = $santa->wallet->gift($child, $item);
198+
199+
// Santa's balance: 0 (paid $100)
200+
// Child received the product
201+
// Merchant balance: $95 (received $100 - $5 fee)
202+
```
203+
204+
## Refunds
205+
206+
When refunding a purchase made with `MerchantFeeDeductible`, the customer receives back what the merchant received (product price minus fee), not what the customer originally paid.
207+
208+
```php
209+
$user = User::first();
210+
$item = Item::first();
211+
212+
// Customer pays $100, merchant receives $95
213+
$user->pay($item);
214+
$user->balance; // 0
215+
$item->balance; // 95
216+
217+
// Refund
218+
$user->refund($item);
219+
$user->balance; // 95 (what merchant received)
220+
$item->balance; // 0
221+
```
222+
223+
## Direct Transfers
224+
225+
When transferring directly to a product that implements `MerchantFeeDeductible`, the fee is deducted from the recipient's deposit.
226+
227+
```php
228+
$user = User::first();
229+
$item = Item::first(); // implements MerchantFeeDeductible
230+
231+
$user->deposit(100);
232+
$user->balance; // 100
233+
234+
// Transfer to merchant
235+
$transfer = $user->transfer($item, 100);
236+
237+
// User balance: 0
238+
// Merchant balance: 95 ($100 - $5 fee)
239+
```
240+
241+
## Key Differences from Taxable
242+
243+
| Feature | Taxable | MerchantFeeDeductible |
244+
|---------|---------|----------------------|
245+
| Customer pays | Product price + fee | Product price only |
246+
| Merchant receives | Product price | Product price - fee |
247+
| Fee location | Added to customer payment | Deducted from merchant payout |
248+
| Use case | Customer covers transaction costs | Merchant covers transaction costs |
249+
250+
It's simple!
251+

0 commit comments

Comments
 (0)