Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Local Payments #2265

Open
wants to merge 81 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
370b14d
feat - Creation of mpesa settings doctype, stk push on billing file"
Sep 4, 2024
0ada507
feat - Mpesa Payment Register to record transactions
Sep 5, 2024
335d05f
feat - Creation of balance transaction after every successfull mpesa …
Sep 9, 2024
7981591
feat - link bank the transaction balance to mpesa payment record
Sep 10, 2024
c052f65
feat - getting partner and team from integration request
Sep 11, 2024
162183d
feat - getting mpesa settings from partner
Sep 12, 2024
8fd8089
feta - adding mpesa button, frontend
Sep 14, 2024
577ce32
fix - set the right api, test with ngrok
Sep 16, 2024
d330ffa
feat - extending BuyPrepaidCreditsForm to cater for KES and Egyption …
Sep 18, 2024
f7bbc3c
feat: local payment
KerollesFathy Sep 19, 2024
33bb5eb
feat - get arguments from frontend for mpesa
Sep 19, 2024
60225fb
feat - select partner functionality
Sep 20, 2024
bd379fd
fix - removal of uncomented code
Sep 20, 2024
e597f87
Merge branch 'ft/local-payment' of https://github.com/Axentorllc/pres…
Sep 24, 2024
a832e50
feat - Update on payment gateway design, added fields in currency exc…
Sep 24, 2024
e4353dc
feat - taxes and total amount calculation for mpesa
Sep 25, 2024
20a2bef
feat - convert from local to USD
Sep 26, 2024
f116e07
feat - front-end to create mpesa settings
Sep 28, 2024
91b67ac
feat(UI): added Buy Prepaid Credits Paymob component
KerollesFathy Sep 30, 2024
c0f2bb2
feat - add tax id to teams, update tax id if missing
Oct 10, 2024
c3b0c4e
Merge branch 'ft/local-payment' of https://github.com/Axentorllc/pres…
Oct 11, 2024
7cfd570
feat - Webhook, generating Invoice from partners site
Oct 12, 2024
432e08e
feat - frontend to display mpesa invoices and allow user to download
Oct 13, 2024
8f601a8
WIP: added Paymob Log, Paymob Settings dt & added accept api
KerollesFathy Oct 15, 2024
423e3b4
WIP: added team name on payment gateway
KerollesFathy Oct 15, 2024
3f47691
WIP: added getPaymentGetway resource & createPaymentIntent and remove…
KerollesFathy Oct 15, 2024
147de4a
WIP: added paymob billing logic
KerollesFathy Oct 15, 2024
2e6116c
WIP: added HMACValidator
KerollesFathy Oct 16, 2024
3a8d83e
WIP: migrate accept api, paymob urls, callbacks to local_payments dir
KerollesFathy Oct 17, 2024
8cd1bc2
WIP: added Paymob Callback Log dt
KerollesFathy Oct 17, 2024
14c4796
WIP: added amount, actual amount, exchange rate on Paymob Log for tra…
KerollesFathy Oct 17, 2024
763536b
WIP: added paymob callbacks urls to allowed paths
KerollesFathy Oct 17, 2024
3cf107f
WIP: added actual amount, currency to payment partner balance transac…
KerollesFathy Oct 17, 2024
af491b0
WIP: pass exchange rate in params
KerollesFathy Oct 17, 2024
0ce7aa0
WIP: added paymob billing file
KerollesFathy Oct 17, 2024
3a81d5f
Fetch exchange rate from teh system
Oct 14, 2024
c322614
feat - limit currency to local people only
Oct 15, 2024
aceefc8
feat - add payment gateway from fronetnd
Oct 19, 2024
3b4541e
feat - code refactor(removing commented code)
Oct 21, 2024
90473db
WIP: some enhancement on UI
KerollesFathy Oct 21, 2024
f318088
WIP: show paymob payment option only for teams from Egypt
KerollesFathy Oct 21, 2024
fbb1cd3
WIP: del client_scrit from intent payload
KerollesFathy Oct 22, 2024
5225fee
WIP: validate HMAC in paymob response callback
KerollesFathy Oct 23, 2024
821ad9d
feat: added Get Access Token button on Paymob Settings dt
KerollesFathy Oct 23, 2024
4000a0c
fix - creating mpesa request log rather than using integration request
Oct 24, 2024
8ec2e56
fix - send amount with tax to user, record amount without tax in the …
Oct 24, 2024
242be74
Merge branch 'ft/local-payment' of https://github.com/Axentorllc/pres…
Oct 24, 2024
17f494f
refactor(accept-api): create AcceptConnection class and streamline re…
KerollesFathy Oct 30, 2024
11477ac
refactor(paymob-billing): standardize naming and enhance payment data…
KerollesFathy Oct 30, 2024
87ff0f2
fix: add error handling and validation to paymob_response_callback
KerollesFathy Oct 31, 2024
c4788ed
refactor: paymob callback log and added payment partner invoice id field
KerollesFathy Oct 31, 2024
803e651
refactor: Payment Partner Balance Transaction
KerollesFathy Oct 31, 2024
83ec01a
fix: ensure payment intent returns a dictionary by default
KerollesFathy Oct 31, 2024
e25f228
fix: ensure payment intent returns a dictionary by default
KerollesFathy Oct 31, 2024
3c3e16a
feat - report for partner to access mpesa transaction
Nov 4, 2024
ac1ce8b
chore - code refactor, put files in correct folders
Nov 7, 2024
4759785
feat - add Partner Payment Transfer doctype for keeping record of sub…
Nov 8, 2024
3713812
feat - Store phone number and update incase there is a change
Nov 12, 2024
d0b5be8
feat - update on partner transfer funds doctype, created patner curre…
Nov 15, 2024
9407a2e
fix - changes on the design of partner balance transaction and partne…
Nov 20, 2024
e27133b
fix: creating payment partner transaction after we renamed the doctype
KerollesFathy Nov 21, 2024
6f3a67c
chore: set default value is Today for posting_date field
KerollesFathy Nov 21, 2024
58cbfcd
fix - after mpesa record, create payment partner transaction which cr…
Nov 22, 2024
1e8c389
feat - Created frontend where partners can initiate transaction to fr…
Nov 22, 2024
dbc53d2
feat(ui): added new component AddPaymobCredentials on Local Payment S…
KerollesFathy Nov 23, 2024
3609dbd
feat: update tax id
KerollesFathy Nov 24, 2024
71c632e
feat - created report for partner payment, fixed a permision issue on…
Nov 25, 2024
38ceebc
chore: remove unused commented code
KerollesFathy Nov 26, 2024
09b74a1
chore: remove invoice id field
KerollesFathy Nov 27, 2024
14ced40
chore: add exchange rate and some data related to both team & payment…
KerollesFathy Nov 27, 2024
20aa393
chore: added new checkbox called success
KerollesFathy Nov 27, 2024
3de660a
chore: rename paymob_utils file
KerollesFathy Nov 27, 2024
3095267
chore: added success field
KerollesFathy Nov 27, 2024
393db59
fix: change options from Mpesa to Payment Partner Transaction
KerollesFathy Dec 1, 2024
f91c3b0
fix: actual amount calculations
KerollesFathy Dec 4, 2024
f95d1a0
test: added tests for Paymob Callback Log
KerollesFathy Dec 4, 2024
254e820
fix: paymob imports
KerollesFathy Dec 13, 2024
ff865f3
fix - convert phone number to string before storing it in mpesa payme…
Dec 11, 2024
edcbde4
chore - minor fix on callback url
Dec 11, 2024
78a06d6
fix - getting the right site address for callback
Dec 17, 2024
2f6aded
chore - removal of comented code and testing values
Dec 17, 2024
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
27 changes: 27 additions & 0 deletions dashboard/src/assets/mpesa.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
157 changes: 157 additions & 0 deletions dashboard/src2/components/AddExchangeRate.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<template>

<Dialog :class="showDialog" :options="{title:'Add Currency Exchange', size:'lg'}">
<template #body-content>
<div class="grid grid-cols-2 gap-4">
<FormControl
label="From Currency"
v-model="fromCurrency"
type="autocomplete"
variant="subtle"
:disabled="false"
:options="currencySymbols"
name="from_currency"
class="mb-5"
required
/>


<FormControl
label="To Currency"
v-model="toCurrency"
name="to_currency"
type="autocomplete"
variant="subtle"
:disabled="false"
:options="currencySymbols"
class="mb-5"
required
/>

<FormControl
label="Exchange Rate"
v-model="exchangeRate"
name="exchange_rate"
autocomplete="off"
class="mb-5"
type="number"
required
/>

<DatePicker
v-model="date"
variant="subtle"
name="date"
placeholder="Placeholder"
:disabled="false"
label="Date"
/>


</div>

<div class="mt-4 flex w-full items-center justify-center">
<Button @click="saveExchangeRate" class="justify-center w-full font-bold" variant="solid" type="primary">Add Currency Exchange</Button>

</div>
</template>
<ErrorMessage class="mt-2" :message="ErrorMessage" />
</Dialog>
</template>

<script>
import {toast} from 'vue-sonner';
import {frappeRequest} from 'frappe-ui';
import {DashboardError} from '../utils/error';
import FormControl from 'frappe-ui/src/components/FormControl.vue';
import DatePicker from 'frappe-ui/src/components/DatePicker.vue';
import ErrorMessage from 'frappe-ui/src/components/ErrorMessage.vue';



export default {
name:'AddExchangeRate',
components:{DatePicker},
props:{
showDialog:{
type: Boolean,
required: true
}
},
data(){
return{
fromCurrency:'',
toCurrency:'',
date:'',
exchangeRate:'',
currencySymbols:[],
}
},

resources:{
addCurrencyExchange(){
return{
url: 'press.api.local_payments.mpesa.utils.create_exchange_rate',
params:{
from_currency: this.fromCurrency,
to_currency: this.toCurrency,
exchange_rate: this.exchangeRate,
date: this.date
},
validate(){
if(!this.fromCurrency || !this.toCurrency || !this.exchangeRate || !this.date){
toast.error('All fields are required');
return false;
}
},
async onSuccess(){
if(data){
toast.success('Currency Exchange Added Successfully');
this.$emit('close');
}else{
toast.error('Failed to add currency exchange');
}
}
}
}
},

methods: {
async saveExchangeRate(){
try{
const response= await this.$resources.addCurrencyExchange.submit();
if (response){
this.$toast.success('Currency Exchange Added Successfully');
this.fromCurrency = '';
this.toCurrency = '';
this.exchangeRate = '';
this.date = '';
}
this.$emit('closeDialog');
}catch(error){
console.log(error);
this.$toast.error(`Error adding currency exchange: ${error.message}`);
}
},

async fetchCurrencySymbols(){
try{
const response = await frappeRequest({
url:'/api/method/press.api.local_payments.mpesa.utils.fetch_currencies',
method:'GET',
});
if(Array.isArray(response)){
this.currencySymbols=response;
}else{
this.ErrorMessage='No currency symbols found';
}
}catch(error){
this.ErrorMessage=`Error fetching currency symbols: ${error.message}`;
}
}
},
mounted(){
this.fetchCurrencySymbols();
}
}
</script>
180 changes: 180 additions & 0 deletions dashboard/src2/components/AddMpesaCredentials.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<template>
<Dialog :class="showDialog" :options="{ title: 'Add M-Pesa Credentials', size: 'lg' }">
<template #body-content>
<div class="grid grid-cols-2 gap-4">
<FormControl
label="Payment Gatway Name"
v-model="paymentGatewayName"
name="consumer_key"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Mpesa setting Name"
required
/>

<FormControl
label="Consumer Key"
v-model="consumerKey"
name="consumer_key"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Consumer Key"
required
/>

<FormControl
label="Consumer Secret"
v-model="consumerSecret"
name="consumer_secret"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Consumer Secret"
required
/>

<FormControl
label="Pass Key"
v-model="passKey"
name="pass_key"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Pass Key"
required
/>

<FormControl
label="Short Code"
v-model="shortCode"
name="short_code"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Short Code"
required
/>

<FormControl
label="Initiator Name"
v-model="initiatorName"
name="initiator_name"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Initiator Name"
required
/>

<FormControl
label="Security Credential"
v-model="securityCredential"
name="security_credential"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Security Credential"
required
/>

<FormControl
label="Till Number"
v-model="tillNumber"
name="till_number"
autocomplete="off"
class="mb-5"
type="text"
placeholder="Enter Till Number"
required
/>

<div class="flex items-center">
<input v-model="sandBox" type="checkbox" class="mr-2" />
<label class="text-sm font-medium text-gray-700">Sandbox Mode</label>
</div>
</div>

<div class="mt-4 flex w-full bg-red-300 items-center justify-center">
<Button @click="saveMpesaCredentials" variant="solid" class="justify-center w-full font-bold">Save</Button>
</div>

</template>
</Dialog>
</template>

<script>
import { toast } from 'vue-sonner';
import { DashboardError } from '../utils/error';
import { ErrorMessage} from 'frappe-ui';
export default {
name: 'AddMpesaCredentials',
props: {
showDialog: {
type: Boolean,
required: true,
},
},
data() {
return {

consumerKey: '',
paymentGatewayName: '',
consumerSecret: '',
passKey: '',
shortCode: '',
initiatorName: '',
securityCredential: '',
tillNumber: '',
sandBox: false,

};
},

resources: {
createMpesaSettings(){
return{
url: 'press.api.local_payments.mpesa.mpesa_settings.create_mpesa_settings',
params:{
payment_gateway_name: this.paymentGatewayName,
consumer_key: this.consumerKey,
consumer_secret: this.consumerSecret,
pass_key: this.passKey,
short_code: this.shortCode,
initiator_name: this.initiatorName,
security_credential: this.securityCredential,
till_number: this.tillNumber,
sandbox: this.sandBox
},

validate(){
if(!this.paymentGatewayName || !this.consumerKey || !this.consumerSecret || !this.passKey || !this.shortCode || !this.initiatorName || !this.securityCredential){
return 'All fields are required';
}
},

async onSuccess(data){
if(data){
toast.success('M-Pesa credentials savedd', data);
}else{
toast.error('Error saving M-Pesa credentials');
}
}

}
}
},

methods: {
async saveMpesaCredentials() {
try {
const response = await this.$resources.createMpesaSettings.submit();
this.$emit('closeDialog');
} catch (error) {
this.$toast.error(`Error saving M-Pesa credentials: ${error.message}`);
}
},
},
};
</script>
Loading