Skip to content

Commit daadb1b

Browse files
authored
Merge pull request #41 from Acode-Foundation/fix-payments
refactor: streamline payment method handling and enforce fixed paymen…
2 parents a167f06 + 1424785 commit daadb1b

8 files changed

Lines changed: 103 additions & 240 deletions

File tree

client/pages/addPaymentMethod/index.js

Lines changed: 29 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,74 +4,43 @@ import Reactive from 'html-tag-js/reactive';
44
import Ref from 'html-tag-js/ref';
55
import { loadingEnd, loadingStart } from 'lib/helpers';
66

7-
export default async function AddPaymentMethod({ mode }) {
7+
export default async function AddPaymentMethod() {
88
const form = Ref();
99
const errorText = Reactive('');
1010
const successText = Reactive('');
1111
const buttonText = Reactive('Save');
12-
let title = 'Add New Bank Account';
12+
const title = 'Add New Bank Account';
1313

14-
if (mode === 'paypal') {
15-
title = 'Add New Paypal Account';
16-
form.append(
17-
<div>
18-
<Input type='email' name='paypal_email' placeholder='e.g. johndoe@gmail.com' label='Paypal Email' />
19-
<span className='error'>{errorText}</span>
20-
<span className='success'>{successText}</span>
21-
<div className='buttons-container'>
22-
<button type='submit' style={{ width: '120px' }}>
23-
Save
24-
</button>
25-
</div>
26-
</div>,
27-
);
28-
} else if (mode === 'bank-account') {
29-
form.append(
30-
<div>
31-
<Input type='text' name='bank_account_holder' placeholder='e.g. John Doe' label='* Account holder' required={true} />
32-
<Input type='text' name='bank_account_number' placeholder='e.g. 98765643210' label='* Account Number' required={true} />
33-
<Input type='text' name='bank_name' placeholder='e.g. ICICI Bank' label='* Bank Name' required={true} />
34-
<Input type='text' name='bank_ifsc_code' placeholder='e.g. ICIC0000282' label='* Bank IFSC Code' required={true} />
35-
<Input type='text' name='bank_swift_code' placeholder='e.g. ICICINBBNRI' label='Bank Swift Code' />
14+
form.append(
15+
<div>
16+
<Input type='text' name='bank_account_holder' placeholder='e.g. John Doe' label='* Account holder' required={true} />
17+
<Input type='text' name='bank_account_number' placeholder='e.g. 98765643210' label='* Account Number' required={true} />
18+
<Input type='text' name='bank_name' placeholder='e.g. ICICI Bank' label='* Bank Name' required={true} />
19+
<Input type='text' name='bank_ifsc_code' placeholder='e.g. ICIC0000282' label='* Bank IFSC Code' required={true} />
20+
<Input type='text' name='bank_swift_code' placeholder='e.g. ICICINBBNRI' label='Bank Swift Code' />
3621

37-
<fieldset>
38-
<legend style={{ marginBottom: '10px' }}>Account type</legend>
39-
<Input type='radio' name='bank_account_type' value='savings' label='Savings' checked={true} />
40-
<Input type='radio' name='bank_account_type' value='current' label='Current' />
41-
</fieldset>
22+
<fieldset>
23+
<legend style={{ marginBottom: '10px' }}>Account type</legend>
24+
<Input type='radio' name='bank_account_type' value='savings' label='Savings' checked={true} />
25+
<Input type='radio' name='bank_account_type' value='current' label='Current' />
26+
</fieldset>
4227

43-
<span className='error'>{errorText}</span>
44-
<span className='success'>{successText}</span>
28+
<span className='error'>{errorText}</span>
29+
<span className='success'>{successText}</span>
4530

46-
<small style={{ marginTop: '20px', display: 'block' }}>
47-
<sup>*</sup> are required.
48-
</small>
49-
<div className='buttons-container'>
50-
<button type='submit' style={{ width: '120px' }}>
51-
{buttonText}
52-
</button>
53-
<button type='reset' className='danger' style={{ width: '120px' }}>
54-
Reset
55-
</button>
56-
</div>
57-
</div>,
58-
);
59-
} else if (mode === 'crypto') {
60-
title = 'Add New Wallet';
61-
form.append(
62-
<div>
63-
<Input required={true} type='text' name='wallet_address' placeholder='e.g. 0x1234567890abcdef' label='Wallet Address' />
64-
<Input required={true} type='text' name='wallet_type' placeholder='e.g. Ethereum' label='Wallet Type' />
65-
<span className='error'>{errorText}</span>
66-
<span className='success'>{successText}</span>
67-
<div className='buttons-container'>
68-
<button type='submit' style={{ width: '120px' }}>
69-
{buttonText}
70-
</button>
71-
</div>
72-
</div>,
73-
);
74-
}
31+
<small style={{ marginTop: '20px', display: 'block' }}>
32+
<sup>*</sup> are required.
33+
</small>
34+
<div className='buttons-container'>
35+
<button type='submit' style={{ width: '120px' }}>
36+
{buttonText}
37+
</button>
38+
<button type='reset' className='danger' style={{ width: '120px' }}>
39+
Reset
40+
</button>
41+
</div>
42+
</div>,
43+
);
7544

7645
return (
7746
<section id='add-payment-method'>

client/pages/earnings/index.js

Lines changed: 10 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import './style.scss';
22
import alert from 'components/dialogs/alert';
3-
import prompt from 'components/dialogs/prompt';
43
import MonthSelect from 'components/MonthSelect';
54
import YearSelect from 'components/YearSelect';
65
import Reactive from 'html-tag-js/reactive';
@@ -10,20 +9,14 @@ import moment from 'moment';
109

1110
let loggedInUser;
1211

13-
export default async function Earnings({ user, threshold }) {
12+
export default async function Earnings({ user }) {
1413
loggedInUser = user;
1514

16-
if (!threshold) {
17-
const userData = await fetchJson(user);
18-
threshold = userData.threshold;
19-
}
20-
2115
const paymentsTable = Ref();
2216
const earningsYear = Ref();
2317
const earningsMonth = Ref();
2418
const paymentsYear = Ref();
2519
const earnings = Reactive('Loading...');
26-
const thresholdText = Reactive(threshold.toLocaleString());
2720

2821
let unpaidEarnings;
2922
try {
@@ -80,9 +73,7 @@ export default async function Earnings({ user, threshold }) {
8073
<tr>
8174
<th>Payment Threshold</th>
8275
<td>
83-
<div on:click={updateThreshold}>
84-
&#8377; {thresholdText} {loggedInUser !== '1' && <span className='icon create' />}
85-
</div>
76+
<div>&#8377; 30,000</div>
8677
<p>
8778
You will be paid when your earnings reach this amount. Please read <a href='/terms'>Terms of Service</a> "Payment threshold" section
8879
for more info.
@@ -115,29 +106,6 @@ export default async function Earnings({ user, threshold }) {
115106
</section>
116107
);
117108

118-
async function updateThreshold() {
119-
const newThreshold = await prompt('Enter new threshold amount', {
120-
type: 'number',
121-
defaultValue: threshold,
122-
});
123-
if (!newThreshold) return;
124-
try {
125-
showLoading();
126-
await fetch('/api/user/threshold', {
127-
method: 'PUT',
128-
headers: {
129-
'Content-Type': 'application/json',
130-
},
131-
body: JSON.stringify({ threshold: newThreshold }),
132-
});
133-
thresholdText.value = newThreshold.toLocaleString();
134-
} catch (error) {
135-
alert('Error', error.message);
136-
} finally {
137-
hideLoading();
138-
}
139-
}
140-
141109
/**
142110
* Renders earnings table
143111
*/
@@ -178,31 +146,19 @@ export default async function Earnings({ user, threshold }) {
178146
}
179147

180148
function Payment(props) {
181-
const { paypal_email: paypalEmail, bank_name: bankName, bank_account_number: bankAccountNumber } = props;
182-
let method;
183-
184-
if (paypalEmail) {
185-
method = (
186-
<div>
187-
<span className='icon paypal' />
188-
<span>{paypalEmail}</span>
189-
</div>
190-
);
191-
} else {
192-
method = (
193-
<div>
194-
<span className='icon bank' />
195-
<span>{bankName}</span>
196-
<span>{bankAccountNumber}</span>
197-
</div>
198-
);
199-
}
149+
const { bank_name: bankName, bank_account_number: bankAccountNumber } = props;
200150

201151
return (
202152
<tr>
203153
<td className='download'>{moment(props.created_at).format('DD MMM YYYY')}</td>
204154
<td className='amount'>&#8377; {props.amount.toLocaleString()}</td>
205-
<td className='payment-method'>{method}</td>
155+
<td className='payment-method'>
156+
<div>
157+
<span className='icon bank' />
158+
<span>{bankName}</span>
159+
<span>{bankAccountNumber}</span>
160+
</div>
161+
</td>
206162
<td className='status'>{props.status}</td>
207163
<td className='download'>
208164
<button type='button' onclick={() => window.open(`/api/user/receipt/${props.id}`, '_blank')} title='download' className='icon download' />

client/pages/termsOfService/website-ts.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,11 @@ You retain ownership of any plugins you upload to our website. However, by uploa
1414

1515
## Payments
1616

17-
We will pay you for your plugin sales and download count. Payments will be made to the bank account or PayPal email address you provide as your default payment method. If your earnings from the previous month(s) sum up to an amount equal to or greater than the threshold, your payment will be automatically transferred to your default payment method on the 16th of each month. If the 16th falls on a weekend, the transfer will occur on the next working day. Please note that it may take up to 5 working days for the amount to be credited to your account. You are responsible for any taxes or fees associated with receiving payments.
17+
We will pay you for your plugin sales and download count. Payments will be made to the bank account you provide as your default payment method. If your earnings from the previous month(s) sum up to an amount equal to or greater than the threshold, your payment will be automatically transferred to your default payment method on the 16th of each month. If the 16th falls on a weekend, the transfer will occur on the next working day. Please note that it may take up to 5 working days for the amount to be credited to your account. You are responsible for any taxes or fees associated with receiving payments.
1818

1919
## Payment Threshold
2020

21-
The payment threshold is the minimum amount of earnings required for a payment to be processed and transferred to your designated payment method. Different minimum thresholds apply depending on the chosen payment method:
22-
23-
- For international payments: The minimum threshold is 5000 INR.
24-
- For payments via cryptocurrency: The minimum threshold is 4000 INR.
25-
- For all other payment methods: The minimum threshold is 1000 INR.
26-
27-
If you choose to change your payment threshold, it cannot be set lower than the respective minimum threshold specified above. However, regardless of the user-set threshold, if the selected payment method falls under one of the mentioned categories, the respective minimum threshold will be applied for processing payments.
21+
The payment threshold is fixed at **₹30,000 INR** for all payment methods. This is the minimum amount of earnings required for a payment to be processed and transferred to your designated payment method. This threshold cannot be changed by users.
2822

2923
Please note that all bank charges and taxes associated with receiving payments will be deducted from the payment amount.
3024

client/pages/user/index.js

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -111,43 +111,14 @@ export default async function User({ userId }) {
111111
this.scrollLeft += e.deltaY;
112112
}
113113

114-
function PaymentMethod({
115-
id,
116-
paypal_email: paypalEmail,
117-
bank_account_number: bankAccountNumber,
118-
bank_account_type: bankAccountType,
119-
is_default: isDefault,
120-
wallet_address: walletAddress,
121-
wallet_type: walletType,
122-
}) {
114+
function PaymentMethod({ id, bank_account_number: bankAccountNumber, bank_account_type: bankAccountType, is_default: isDefault }) {
123115
isDefault = isDefault ? 'default' : '';
124-
let title = paypalEmail ? `PayPal ${paypalEmail}` : `${bankAccountType} ${bankAccountNumber}`;
116+
let title = `${bankAccountType} ${bankAccountNumber}`;
125117

126118
if (isDefault) {
127119
title += ' (default)';
128120
}
129121

130-
if (paypalEmail) {
131-
return (
132-
<div on:click={onPaymentMethodClick} title={title} data-id={id} className='payment-method' data-default={isDefault}>
133-
<span className='icon paypal' />
134-
<span className='info'>{paypalEmail}</span>
135-
</div>
136-
);
137-
}
138-
139-
if (walletAddress && walletType) {
140-
return (
141-
<div on:click={onPaymentMethodClick} data-id={id} title={title} className='payment-method' data-default={isDefault}>
142-
<span className='icon bitcoin' />
143-
<div className='info'>
144-
<strong>{walletType}</strong>
145-
<span>{walletAddress}</span>
146-
</div>
147-
</div>
148-
);
149-
}
150-
151122
return (
152123
<div on:click={onPaymentMethodClick} data-id={id} title={title} className='payment-method' data-default={isDefault}>
153124
<span className='icon account_balance' />
@@ -207,8 +178,7 @@ export default async function User({ userId }) {
207178
* Add payment method
208179
*/
209180
async function addPaymentMethod() {
210-
const option = await select('Add payment method', ['Paypal', 'Bank account', 'Crypto']);
211-
Router.loadUrl(`/add-payment-method/${option.toLowerCase().replace(' ', '-')}`);
181+
Router.loadUrl('/add-payment-method/bank-account');
212182
}
213183

214184
async function renderPaymentMethods() {
@@ -248,7 +218,7 @@ export default async function User({ userId }) {
248218
amount.el.parentElement.onclick = async () => {
249219
Router.setUrl(`/earnings?user=${user.id}`);
250220
showLoading();
251-
tag.get('main').content = await Earnings({ user: user.id, threshold: user.threshold });
221+
tag.get('main').content = await Earnings({ user: user.id });
252222
hideLoading();
253223
};
254224
} catch (error) {

constants.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export const ALLOWED_CALLBACK_HOSTS_ARRAY = ['acode.app', ...(process.env.NODE_ENV === 'development' ? ['localhost:5500'] : [])];
2+
export const PAYMENT_THRESHOLD = 30000;

0 commit comments

Comments
 (0)