Skip to content

Commit

Permalink
Merge pull request #6 from fikremariamF/split-payment-and-handle-webh…
Browse files Browse the repository at this point in the history
…ook-features

feat: add functions for create sub account, webhook validation, get banks, and bulk transfer
  • Loading branch information
isrugeek authored Oct 23, 2024
2 parents 7dc0eea + b17c8e6 commit 7728adb
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 13 deletions.
60 changes: 59 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,26 @@ The current features have been implemented
- Payment verification
- Create a Transfer
- Verify a Transfer
- Validate a Webhook Request
- Bulk Transfer
- Create Subaccount

## API Reference
### Create Subaccount

```https
GET https://api.chapa.dev/v1/transaction/sub-accounts
```

| Parameter | Type | Required | Description |
| :-------- | :------- | :------- | :------------------------------------------------------------------------------------------------------------------- |
| `business_name` | `string` | **Yes**. | The name of the business or vendor. |
| `account_name` | `string` | **Yes**. | The name of the account holder, which must match the bank account details. |
| `bank_code` | `integer` | **Yes**. | The ID of the bank where the subaccount is held. You can retrieve this from the "Get Banks" endpoint. |
| `account_number` | `string` | **Yes**. | The bank account number for the subaccount |
| `split_type` | `string` | **Yes**. | Defines how the payment will be split. Can be "percentage" or "flat". |
| `split_value` | `float` | **Yes**. | The value of the split. If split_type is percentage, this represents a percentage (e.g., 0.03 for 3%). |
| | | | If split_type is flat, this represents a fixed amount in ETB (e.g., 25 for 25 Birr). |

### Collecting Customer Information

Expand All @@ -61,8 +79,9 @@ The current features have been implemented
| `callback_url` | `string` | **No**. | Function that runs when payment is successful. This should ideally be a script that uses the verify endpoint on the Chapa API to check the status of the transaction. |
| `return_url` | `string` | **No**. | A web address provided by the merchant to a payment gateway during payment integration. It serves as the destination where the payment gateway sends the customer after completing a payment transaction. |
| `currency` | `string` | **Yes**. | The currency in which all the charges are made. Currency allowed is ETB. |
| `customization[tiitle] ` | `string` | **No**. | The customizations field (optional) allows you to customize the look and feel of the payment modal. You can set a logo, the store name to be displayed (title), and a description for the payment.. |
| `customization[tiitle] ` | `string` | **No**. | The customizations field (optional) allows you to customize the look and feel of the payment modal. You can set a logo, the store name to be displayed (title), and a description for the payment. |
| `customization[description]` | `string` | **No**. | The customizations field (optional) allows you to customize the look and feel of the payment modal. |
| `customization[subaccounts][id] ` | `string` | **Yes**. | The customization field is optional. The subaccounts field within customization is also optional, but if provided, each subaccount must include an id (required). The payment will be split among the subaccounts based on the specified split_type and split_value. |

### Verify Payments

Expand All @@ -86,6 +105,45 @@ The current features have been implemented
| :-------- | :------- | :------- | :------------------------------------------------------------------------------------------------------------------- |
| `key` | `string` | **Yes**. | This will be your public key from Chapa. When on test mode use the test key, and when on live mode use the live key. |



### Bulk Transfers

```https
GET https://api.chapa.dev/v1/bulk-transfers
```

| Parameter | Type | Required | Description |
| :-------- | :------- | :------- | :------------------------------------------------------------------------------------------------------------------- |
| `title` | `string` | **Yes**. | This will be your title or desciption for bulk transfer. |
| `currency` | `string` | **Yes**. | The currency for the transfers (e.g., ETB for Ethiopian Birr). |
| `bulk_data` | `array` | **Yes**. |An array of individual transfers containing the following fields: |
| `bulk_data[].account_name` | `string` | **Yes**. | The name of the account holder for the transfer. |
| `bulk_data[].account_number` | `string` | **Yes**. | The account number to which the transfer will be made. |
| `bulk_data[].amount` | `integer` | **Yes**. | The amount to be transferred. |
| `bulk_data[].reference` | `string` | **Yes**. | A unique reference for the individual transfer (used for tracking purposes). |
| `bulk_data[].bank_code` | `integer` | **Yes**. | The bank code of the recipient's bank (get the code via Chapa’s banks API). |


### Get Banks
The Get Banks API retrieves a list of banks available for transfers via the Chapa API. This is useful when you need to display a list of banks for users to select from or when you need bank codes for initiating transactions.



### Verify Webhooks
This function validates incoming webhook events from Chapa to ensure their authenticity. It checks the signature of the webhook against an expected signature, generated using the webhook payload and a secret key. If the signatures match, the webhook is considered valid.

#### Parameters:
- **`$request`** *(Illuminate\Http\Request)*: The incoming HTTP request containing the webhook payload and headers. The key header used for validation is:
- **`x-chapa-signature`**: A header sent by Chapa containing the HMAC-SHA256 signature of the webhook payload. This signature is used to verify the authenticity of the webhook.

#### Returns:
- **`boolean`**:
- `true`: If the webhook is valid (i.e., the signature matches).
- `false`: If the webhook is invalid (i.e., the signature does not match).



### Changelog

Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
Expand Down
87 changes: 75 additions & 12 deletions src/Chapa.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class Chapa
{

/**
* Generates a unique reference
* @param $transactionPrefix
Expand All @@ -21,19 +21,34 @@ class Chapa

function __construct()
{

$this->secretKey = env('CHAPA_SECRET_KEY');
$this->baseUrl = 'https://api.chapa.co/v1';

}

public static function generateReference(String $transactionPrefix = NULL)
}

public static function generateReference(string $transactionPrefix = NULL)
{
if ($transactionPrefix) {
return $transactionPrefix . '_' . uniqid(time());
}

return env('APP_NAME').'_'.'chapa_' . uniqid(time());

return env('APP_NAME') . '_' . 'chapa_' . uniqid(time());
}

/**
* Create Subaccount.
* @param array $data
* @return array
*/
public function createSubaccount(array $data)
{
$response = Http::withToken($this->secretKey)->post(
$this->baseUrl . '/sub-accounts',
$data
)->json();

return $response;
}

/**
Expand All @@ -49,10 +64,10 @@ public function initializePayment(array $data)
$data
)->json();

return $payment;
return $payment;
}

/**
/**
* Gets a transaction ID depending on the redirect structure
* @return string
*/
Expand All @@ -74,7 +89,7 @@ public function getTransactionIDFromCallback()
*/
public function verifyTransaction($id)
{
$data = Http::withToken($this->secretKey)->get($this->baseUrl . "/transaction/" . 'verify/'. $id )->json();
$data = Http::withToken($this->secretKey)->get($this->baseUrl . "/transaction/" . 'verify/' . $id)->json();
return $data;
}
/**
Expand All @@ -90,7 +105,7 @@ public function createTransfer(array $data)
$data
)->json();

return $transfer;
return $transfer;
}

/**
Expand All @@ -100,8 +115,56 @@ public function createTransfer(array $data)
*/
public function verifyTransfer($id)
{
$data = Http::withToken($this->secretKey)->get($this->baseUrl . "/transfers/" . 'verify/'. $id )->json();
$data = Http::withToken($this->secretKey)->get($this->baseUrl . "/transfers/" . 'verify/' . $id)->json();
return $data;
}

/**
* Validate incoming webhook event is from Chapa.
*
* @param $request
* @return boolean
*/
public function validateWebhook($request)
{
$signature = $request->header('x-chapa-signature');
$expectedSignature = hash_hmac('sha256', $request->getContent(), env('CHAPA_WEBHOOK_SECRET'));

if ($signature !== $expectedSignature) {
return false;
}
return true;
}

/**
* Initiates a bulk transfer.
* @param array $data
* @return array
*/
public function bulkTransfer(array $data)
{
$response = Http::withToken($this->secretKey)->post(
$this->baseUrl . '/bulk-transfers',
$data
)->json();

return $response;
}

/**
* Gets a list of banks
*
* @return array
*/
public function getBanks()
{
// Send a GET request to Chapa's /v1/banks endpoint
$response = Http::withToken($this->secretKey)
->get($this->baseUrl . "/banks")
->json();

// Return the response data
return $response;
}

}

0 comments on commit 7728adb

Please sign in to comment.