Skip to content

Commit 472956e

Browse files
authored
Multi-Split Payment feature [using the newcode structure in Main Branch] (#172)
* feat: Add the Multi-Split Payment Feature This adds the Multi-Split Payment Feature as documented by Paystack (https://paystack.com/docs/payments/multi-split-payments/). This include using split_code and dynamic splits, which comes in handy in creating splits on the fly. * docs: Update the README file Update the README file with information on the Multi-Split Payment feature
1 parent f938c38 commit 472956e

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ function Pay(){
119119
| `billingMobile` | Billers mobile | default: `nill` |
120120
| `billingName` | Billers Name | default: `nill` |
121121
| `subaccount` | Specify subaccount code generated from the Paystack Dashboard or API to enable Split Payment on the transaction. Here's an example of usage: `subaccount: "SUB_ACCOUNTCODE"` | default: `nill` |
122+
| `split_code` | Specify _split_code_ generated from the Paystack Dashboard under _Transaction Splits menu_ or API to enable Multi-Split Payment on the transaction. According to Paystack's documentation available [here](https://paystack.com/docs/payments/multi-split-payments/), Multi-split enables merchants to split the settlement for a transaction across their payout account, and one or more subaccounts. Here's an example of usage: `split_code: "SPL_xxxxxxx"` | default: `nill` |
123+
| `split` | Specify _split_ object to enable Dynamic Multi-Split Payment on the transaction. According to Paystack's documentation available [here](https://paystack.com/docs/payments/multi-split-payments/#dynamic-splits), Sometimes, you can't determine a split configuration until later in the purchase flow. With dynamic splits, you can create splits on the fly. The Structure is defined [in the Dynamic Multi-Split Structure below](#dynamic-multi-split-payment-object-structure) | default: `nill` |
122124
| `channels` | Specify payment options available to users. Available channel options are: ["card", "bank", "ussd", "qr", "mobile_money"]. Here's an example of usage: `channels={["card","ussd"]}` | default: `["card"]` |
123125
| `onCancel` | callback function if user cancels or payment transaction could not be verified. In a case of not being verified, transactionRef number is also returned in the callback | default: `nill` |
124126
| `onSuccess` | callback function if transaction was successful and verified (it will also return the transactionRef number in the callback ) | default: `nill` |
@@ -127,6 +129,26 @@ function Pay(){
127129
| `handleWebViewMessage` | Will be called when a WebView receives a message | default: `true` |
128130

129131

132+
133+
#### Dynamic Multi-Split Payment Object structure
134+
135+
| Name | use/description | required? |
136+
| :----------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ---------------------------------------------------------: |
137+
| `type` | Dynamic Multi-Split type. Value can be `flat` or `percentage` | `YES` |
138+
| `bearer_type` | Defines who bears the charges. Value can be `all`, `all-proportional`, `account` or `subaccount` | `YES` |
139+
| `subaccounts` | An array of subaccount object as defined [below](#dynamic-multi-split-payment-sub-account-object-structure). e.g. {"subaccount": 'ACCT_xxxxxx', "share": 60} | `YES` |
140+
| `bearer_subaccount` | Subaccount code of the bearerof the transaction. It should be specified if _bearer_type_ is `subaccount` | `NO` |
141+
| `reference` | Unique reference of the split. Can be defined by the user | `NO` |
142+
143+
144+
#### Dynamic Multi-Split Payment Sub-Account Object structure
145+
146+
| Name | use/description | required? |
147+
| :----------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | ---------------------------------------------------------: |
148+
| `subaccount` | Specify subaccount code generated from the Paystack Dashboard or API to enable Split Payment on the transaction. Here's an example of usage: `subaccount: "SUB_ACCOUNTCODE"` | `YES` |
149+
| `share` | Defines the amount in `percentage (integer)` or `value (decimal allowed)` depending on the type of multi-split defined | `YES` |
150+
151+
130152
## [](https://github.com/just1and0/object-to-array-convert#contributions)Contributions
131153

132154
Want to help improve this package? [Read how to contribute](https://github.com/just1and0/React-Native-Paystack-WebView/blob/main/CONTRIBUTING.md) and feel free to submit your PR!

development/paystack.tsx

+17-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useState, useEffect, forwardRef, useRef, useImperativeHandle } from 're
33
import { Modal, View, ActivityIndicator, SafeAreaView } from 'react-native';
44
import { WebView, WebViewNavigation } from 'react-native-webview';
55
import { getAmountValueInKobo, getChannels } from './helper';
6-
import { PayStackProps, PayStackRef } from './types';
6+
import { PayStackProps, PayStackRef, DynamicMultiSplitProps } from './types';
77

88
const CLOSE_URL = 'https://standard.paystack.co/close';
99

@@ -20,6 +20,8 @@ const Paystack: React.ForwardRefRenderFunction<React.ReactNode, PayStackProps> =
2020
refNumber,
2121
billingName,
2222
subaccount,
23+
split_code,
24+
split,
2325
handleWebViewMessage,
2426
onCancel,
2527
autoStart = false,
@@ -51,10 +53,22 @@ const Paystack: React.ForwardRefRenderFunction<React.ReactNode, PayStackProps> =
5153
}
5254
};
5355

56+
const dynamicSplitObjectIsValid = (split:DynamicMultiSplitProps|undefined): split is DynamicMultiSplitProps => {
57+
if ( split !== null && (typeof split === "object") && (split.type) && (split.bearer_type) && (split.subaccounts)) {
58+
return true;
59+
} else { return false; }
60+
}
61+
5462
const refNumberString = refNumber ? `ref: '${refNumber}',` : ''; // should only send ref number if present, else if blank, paystack will auto-generate one
5563

5664
const subAccountString = subaccount ? `subaccount: '${subaccount}',` : ''; // should only send subaccount with the correct subaccoount_code if you want to enable split payment on transaction
5765

66+
const splitCodeString = split_code ? `split_code: '${split_code}',` : ''; // should only send split_code with the correct split_code from the split group if you want to enable multi-split payment on transaction
67+
//Multi-split enables merchants to split the settlement for a transaction across their payout accounts, and one or more subaccounts
68+
69+
const dynamicSplitString = dynamicSplitObjectIsValid(split) ? `split: ` + JSON.stringify(split) + `,` : ''; // should only send split for dynamic multi-account split with the correct split object as defined
70+
//Sometimes, you can't determine a split configuration until later in the purchase flow. With dynamic splits, you can create splits on the fly. This can be achieved by passing a split object
71+
5872
const Paystackcontent = `
5973
<!DOCTYPE html>
6074
<html lang="en">
@@ -81,6 +95,8 @@ const Paystack: React.ForwardRefRenderFunction<React.ReactNode, PayStackProps> =
8195
${getChannels(channels)}
8296
${refNumberString}
8397
${subAccountString}
98+
${splitCodeString}
99+
${dynamicSplitString}
84100
metadata: {
85101
custom_fields: [
86102
{

development/types/index.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,29 @@ export type Currency = 'NGN' | 'GHS' | 'USD' | 'ZAR';
33

44
export type PaymentChannels = 'bank' | 'card' | 'qr' | 'ussd' | 'mobile_money';
55

6+
export type SplitTypes = 'flat' | 'percentage';
7+
8+
export type ChargeBearerTypes = 'all' | 'all-proportional' | 'account' | 'subaccount';
9+
610
interface Response {
711
status: string;
812
}
913
interface SuccessResponse extends Response {
1014
transactionRef?: string;
1115
data?: any;
1216
}
17+
interface DynamicSplitSubAccountInterface {
18+
subaccount: string;
19+
share: string;
20+
}
21+
22+
export interface DynamicMultiSplitProps {
23+
type: SplitTypes;
24+
bearer_type: ChargeBearerTypes;
25+
subaccounts: DynamicSplitSubAccountInterface[];
26+
bearer_subaccount?: string; // only if bearer_type is 'subaccount'
27+
reference?: string;
28+
}
1329

1430
export interface PayStackProps {
1531
paystackKey: string;
@@ -22,7 +38,9 @@ export interface PayStackProps {
2238
channels?: PaymentChannels[];
2339
refNumber?: string;
2440
billingName?: string;
25-
subaccount?: string;
41+
subaccount?: string;
42+
split_code?: string;
43+
split?: DynamicMultiSplitProps;
2644
handleWebViewMessage?: (string: string) => void;
2745
onCancel: (Response: Response) => void;
2846
onSuccess: (SuccessResponse:SuccessResponse) => void;

0 commit comments

Comments
 (0)