Skip to content

Commit

Permalink
Merge pull request #59 from veritrans/v2.30-major-update
Browse files Browse the repository at this point in the history
V2.30 major update
  • Loading branch information
rizdaprasetya authored Aug 6, 2021
2 parents 9bd6102 + 8ae614a commit 0dcc7bd
Show file tree
Hide file tree
Showing 75 changed files with 1,088 additions and 116 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
tests/
tests/
.DS_Store
120 changes: 120 additions & 0 deletions MAINTAINING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
### Overview of Code Structures
- /abstract: contains abstract/interface class
- abstract.midtrans-gateway.php: refer to that file comments. Main blueprint implementation for the main gateway
- abstract.midtrans-gateway-sub.php: refer to that file comments. main blueprint implementation for the Separated Payment Buttons gateway, see below section.
- /class: the concrete class implementations for each of
- /midtrans-gateway.php: refer to that file comments.
- /lib: Midtrans API PHP library, commited dependency, need be manually updated to latest Midtrans PHP library on github/composer
- /js: folder for JS file asset on PG config page on WP admin panel
- /public: public asset folder for images, css, js on customer facing UI
- /images/payment-methods: folder of payment method icons
- all image directly used should not be prefixed with `alt_`
- if filename is prefixed with `alt_`, it is not directly used, and only there as alternative image.
- /resources: like library or helper folder, which may no longer be used? @TODO: remove this?
- /readme: required file, act as WP plugin manifest, see [this reference](https://wordpress.org/plugins/readme.txt).

Other:
- WC/WP have hook functions that will be auto called when certain action are triggered on WC system, e.g: when payment is initiated, when refund occurs, when thank you page showed, etc.
- see ref of "docs WC Payment Gateway" below, to know which functions are built-in function from WC. If not defined there, likely it is our own custom/helper function.
- so most of functions implemented in the code are to implement those built-in functions.

#### References:
- WC PG development guide: https://docs.woocommerce.com/document/payment-gateway-api/
- docs WC Order: https://woocommerce.github.io/code-reference/classes/WC-Order.html
- docs WC Payment Gateway: https://woocommerce.github.io/code-reference/classes/WC-Payment-Gateway.html
- WC hooks guide: https://woocommerce.github.io/code-reference/hooks/hooks.html
- official WP plugin dev guide: https://developer.wordpress.org/plugins/intro/
- sample [PG plugin implementation](https://github.com/woocommerce/woocommerce-gateway-stripe/) from official WC team. [Some other](https://github.com/woocommerce?q=gateway&type=&language=&sort=).
- External WC PG dev guide: https://www.skyverge.com/blog/how-to-create-a-simple-woocommerce-payment-gateway/
- WP get_options() functions: https://developer.wordpress.org/reference/functions/get_option/

### Separted Payment Buttons
To implement separated payment buttons (separate WC payment gateway) for each of Midtrans' supported payment methods, the following implementations are made:
- within `/class/sub-specific-buttons` those are the class files
- these class extends abstract `/abstract/abstract.midtrans-gateway-sub.php`
- which extends main gateway/button `/class/abstract.midtrans-gateway.php`, and most of the core logic are using the logic in implemented in this file. Like: Snap API calling, Notif handling, etc.
- which extends main abstract `/abstract/abstract.midtrans-gateway.php`
- so becareful when modifying these chain of files, as it may impact many other files.
- each of them is imported into `/midtrans-gateway.php` to register the buttons into WC

Quick guide to add new separate button for future payment methods:
- copy one of the file at `/class/sub-specific-buttons`, e.g: `class.midtrans-gateway-sub-gopay.php` as template. Rename the new file into e.g: `class.midtrans-gateway-sub-bni-va.php`
- within the file, replace all the `gopay` keyword with the new payment method's keyword e.g: `bni_va`
- mind the upper/lower case
- within file `/midtrans-gateway.php`:
- add code to import `
require_once dirname( __FILE__ ) . '/class/sub-specific-buttons/class.midtrans-gateway-sub-bni-va.php';`
- add code to register WC gateway `
$methods[] = 'WC_Gateway_Midtrans_Sub_BNI_VA';`
- add new image files (for the payment method's icon) into `/public/images/payment-methods`. e.g: `bni_va.png`
- also change the image file names values, you can refer to the file's code comments.

Alternatively, you can also refer to commit history of when a separate button is added, for example one commit w/ msg: `add basic separate button gateway: card`.

Note: this section may not be frequently updated and may become outdated. In the case the code itself is more updated than this section, please refer to the code itself.

### User Guide
- Some of specific featues of this plugins are documented on Github wiki: https://github.com/veritrans/SNAP-Woocommerce/wiki. @TODO: need to centralize this to Midtrans tech docs?
- Some are in [README.md](./README.md)
- Some are in [Midtrans tech docs](https://docs.midtrans.com/en/snap/with-plugins?id=wordpress-woocommerce)

### Releasing / Publishing Plugins to Wordpress
Plugin WP Hosted url: https://wordpress.org/plugins/midtrans-woocommerce/

**HOW TO:**

#### Prepare: Clone svn repo from Wordpress to local
- This step only required once, to make sure you have the svn cloned on local folder
- Prepare a separated folder from this github repo folder on your local
- Clone the SVN Repo URL: https://plugins.svn.wordpress.org/midtrans-woocommerce/
- Ref on SVN guidelines:
- https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/
- https://developer.wordpress.org/plugins/wordpress-org/how-to-use-subversion/
- https://developer.wordpress.org/plugins/wordpress-org/plugin-developer-faq/
- https://wordpress.org/plugins/about/readme.txt
- https://wordpress.org/plugins/about/validator/
- https://developer.wordpress.org/plugins/wordpress-org/plugin-assets/
- Run `svn update` to get update from remote repo to local repo

#### Update plugin
- On Github repo folder, update version compatibility & tested up to in these files:
- `midtrans-gateway.php`:
- `Version:` {current plugin version: x.x.x}
- `WC tested up to:` {latest WC version: x.x.x}
- `readme.txt`:
- `Requires at least:` {min version of WP, rarely changes: x.x.x}
- `Tested up to:` {latest WP version: x.x.x}
- `Stable tag:` {latest/stable version of this plugin (must have its own /trunk folder): x.x.x}
- Copy contents of Github root folder `Snap-Woocommerce` into your SVN folder, under `/trunk` folder
- Create new folder under `/tags` folder, name it with the plugin version. e.g: `2.6.3`
- Ensure `Stable tag` value within `readme.txt` in folder `trunk` have the same value as above e.g: `2.6.3`
- values that need to be consistent:
- stable tag in readme.txt `/trunk`
- stable tag in readme.txt `/tags/[new version folder]`
- version in `midtrans-gateway.php`

Note, alternatively can also:
- First, svn push the `/tags/[new version folder]`, ensure have been pushed on WP svn.
- Then, edit the readme / trunks version value to match the new version, then push svn again.

Note, if you are deleting commited files:
- SVN will not auto remove files commited in repo, removing commited files in SVN need to be 1by1, here is helper script to bulk remove commited files:
- run script in terminal from your svn repo: `svn rm $( svn status | sed -e '/^!/!d' -e 's/^!//' )`
- src: https://stackoverflow.com/a/9600437

#### Push to SVN
Run terminal command:
- `svn add tags/*`
- `svn add trunk/*`
- `svn add assets/*`
- `svn ci -m '<commit message>' --username <your WP SVN username> --password <your WP SVN password>`

Alternatively, can also create helper script `update_and_push_to_wp.sh` file:
```
#!/usr/bin/env bash
svn add tags/* --force;
svn add trunk/* --force;
svn add assets/* --force;
# svn up;
svn ci -m 'update' <your WP SVN username> --password <your WP SVN password>;
```
60 changes: 60 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,17 @@ Additional payment options (radio button) can be activated:
- Offline Installment
- Promo / specific payment

#### Customize Payment Icons

You can customize icon that will be shown on payment buttons, from the plugin configuration page on your WooCommerce portal, under `Button Icons` config field.

All available values for the field:
```
credit_card.png, gopay.png, shopeepay.png, qris.png, other_va.png, bni_va.png, bri_va.png, bca_va.png, permata_va.png, echannel.png, alfamart.png, indomaret.png, akulaku.png, bca_klikpay.png, cimb_clicks.png, danamon_online.png, midtrans.png
```

Or refer to [payment-methods folder](/public/images/payment-methods) to see the list of all available file names. The image file will be loaded from that folder.

#### BCA Klikpay Specific

<details><summary>Click to expand info</summary>
Expand Down Expand Up @@ -110,6 +121,55 @@ If required to change API endpoint/url, these are where you need to change:
- Replace any Snap API domain: https://app.sandbox.midtrans.com with UAT API domain
</details>

#### Available Custom Hooks

<details><summary>Click to expand info</summary>
<br>

If you are a developer or know how to customize Wordpress, this section may be useful for you in case you want to customize some code/behaviour of this plugin.

This plugin have few available [WP hooks](ttps://developer.wordpress.org/plugins/hooks/):
- filter: `midtrans_snap_params_main_before_charge` (1 params)
- For if you want to modify Snap API JSON param on the main gateway, before transaction is created on Midtrans side.
- action: `midtrans_after_notification_payment_complete` (2 params)
- For if you want to perform action/update WC Order object when the payment is declared as complete upon Midtrans notification received.
- action: `midtrans_on_notification_received` (2 params)
- For if you want to perform action/update WC Order object upon Midtrans notification received.

Example implementation:
```php
// Custom filter hook to modify Snap params
add_filter( 'midtrans_snap_params_main_before_charge', 'my_midtrans_snap_param_hook' );
function my_midtrans_snap_param_hook( $params ) {
// example: modify Snap params to add additional item with 0 price
$params['item_details'][] = array(
"name" => "My Custom Additional Item",
"id" => "my-item-01",
"price" => 0,
"quantity" => 3,
);
// don't forget to return the $params
return $params;
}

// Custom action hook to modify WC Order object after payment marked as complete
add_action( 'midtrans_after_notification_payment_complete', 'my_midtrans_complete_hook',$priority = 10, $accepted_args = 2 );
function my_midtrans_complete_hook( $order, $midtrans_notification ) {
// example: update order status to directly `completed`, instead of default `processing`.
$order->update_status('completed',__('Completed payment via my custom hook: Midtrans-'.$midtrans_notification->payment_type,'midtrans-woocommerce'));
}

// Custom action hook to modify WC Order object when midtrans notification is received
add_action( 'midtrans_on_notification_received', 'my_midtrans_on_notif_hook',$priority = 10, $accepted_args = 2 );
function my_midtrans_on_notif_hook( $order, $midtrans_notification ) {
// do as you wish here
}
```

For reference on where/which file to apply that code example, [refer here](https://blog.nexcess.net/the-right-way-to-add-custom-functions-to-your-wordpress-site/).

</details>

#### Customizing Snap API parameters

<details><summary>Click to expand info</summary>
Expand Down
148 changes: 148 additions & 0 deletions abstract/abstract.midtrans-gateway-sub.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?php
if (! defined('ABSPATH')) {
exit;
}

/**
* WC_Gateway_Midtrans_Abstract_Sub Class
* Abstract class prototype to be extended by sub gateway separated buttons.
* Because Midtrans WC plugins have separate buttons for each payment methods.
*/
abstract class WC_Gateway_Midtrans_Abstract_Sub extends WC_Gateway_Midtrans_Abstract {

/**
* Constructor
*/
function __construct() {
// $this->id = ''; // override me. sample: 'midtrans_sub_other_va';
// $this->sub_payment_method_params = []; // override me. sample: ['other_va'];
// $this->sub_payment_method_image_file_names_str_final = []; // override me. sample: 'other_va.png,other_va_2.png';
// override above values when extending this class

$this->method_title = __( $this->pluginTitle(), 'midtrans-woocommerce' );
$this->method_description = __( $this->getSettingsDescription(), 'midtrans-woocommerce');
$this->main_gateway = false;

parent::__construct();
add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( &$this, 'process_admin_options' ) );
// maybe replace $this->id with main gateway id?
add_action( 'woocommerce_receipt_' . $this->id, array( $this, 'receipt_page' ) );// Payment page hook
}

/**
* Hook function that will be auto-called by WC, this determine what will be shown on Gateway config page on WP panel
* Admin Panel Options
* - Options for bits like 'title' and availability on a country-by-country basis
* @access public
* @return void
*/
public function admin_options() { ?>
<h3><?php _e( $this->pluginTitle(), 'midtrans-woocommerce' ); ?></h3>
<p><?php _e( $this->getSettingsDescription(), 'midtrans-woocommerce' ); ?></p>
<table class="form-table">
<?php
// Generate the HTML For the settings form. Built in WC function
$this->generate_settings_html();
?>
</table><!--/.form-table-->
<?php
}

/**
* Initialise Gateway Settings Form Fields
* Hook function that will be auto-called by WC, this determine what will be shown on Gateway config page on WP panel, likely called from generate_settings_html() above.
*/
function init_form_fields() {
$this->form_fields =
apply_filters(
'wc_midtrans_settings',
array(
'enabled' => array(
'title' => __( 'Enable/Disable', 'midtrans-woocommerce' ),
'type' => 'checkbox',
'label' => __( 'Enable this specific payment methods', 'midtrans-woocommerce' ),
'default' => 'no'
),
'title' => array(
'title' => __( 'Payment Title', 'midtrans-woocommerce' ),
'type' => 'text',
'description' => __( 'This controls the payment label title which the user sees during checkout. <a href="https://github.com/veritrans/SNAP-Woocommerce#configurables" target="_blank">This support HTML tags</a> like &lt;img&gt; tag, if you want to include images.', 'midtrans-woocommerce' ),
'placeholder' => $this->getDefaultTitle(),
'default' => $this->getDefaultTitle(),
// 'desc_tip' => true,
),
'description' => array(
'title' => __( 'Payment Description', 'midtrans-woocommerce' ),
'type' => 'textarea',
'description' => __( 'You can customize here the expanded description which the user sees during checkout when they choose this payment. <a href="https://github.com/veritrans/SNAP-Woocommerce#configurables" target="_blank">This support HTML tags</a> like &lt;img&gt; tag, if you want to include images.', 'midtrans-woocommerce' ),
'placeholder' => $this->getDefaultDescription(),
'default' => $this->getDefaultDescription(),
),
'advanced_config_separator' => array(
'title' => __( 'Note:', 'midtrans-woocommerce' ),
'type' => 'title',
'description' => __( 'Other configurations by default will follow main Midtrans Payment plugin config'),
),
)
);
}
/**
* Override Hook function that will be auto-called by WC on customer initiate payment
* act as entry point when payment process is initated
* @param string $order_id generated from WC
* @return array contains redirect_url of payment for customer
*/
function process_payment( $order_id ) {
$main_gateway = $this->getMainGatewayObject();
// pass through the real function from main gateway implementation, with options params
return $main_gateway->process_payment_helper(
$order_id,
array('sub_payment_method_params' => $this->sub_payment_method_params)
);
}

/**
* Hook function that will be auto-called by WC on receipt page
* Output HTML for Snap payment page. Including `snap.pay()` part
* @param string $order_id generated by WC
* @return string HTML
*/
function receipt_page( $order_id ) {
// pass through the real function from main gateway implementation
$main_gateway = $this->getMainGatewayObject();
return $main_gateway->receipt_page($order_id);
}

/**
* @return string Title for plugin config page
*/
abstract public function pluginTitle ();

/**
* @return string Description for plugin config page
*/
abstract public function getSettingsDescription ();

/**
* @return string Config field: Title for pay button label for customer
*/
abstract protected function getDefaultTitle ();

/**
* @return string Config field: Description for pay button label for customer
*/
abstract protected function getDefaultDescription ();

/**
* @return WC_Gateway_Midtrans
*/
protected function getMainGatewayObject(){
if ($this->main_gateway && $this->main_gateway->id) {
// main gateway exist, do nothing
} else {
$this->main_gateway = new WC_Gateway_Midtrans();
}
return $this->main_gateway;
}

}
Loading

0 comments on commit 0dcc7bd

Please sign in to comment.