diff options
| author | Shulhan <ms@kilabit.info> | 2023-01-31 21:24:45 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-02-01 11:02:09 +0700 |
| commit | b4b6699c27b04893c73c50553070682799220080 (patch) | |
| tree | 2579635e56702449a6427ac0a8586524e2adf3b6 | |
| parent | d8b4bd20f3755a1f323c3a563167f240cdb11e23 (diff) | |
| download | duitku-b4b6699c27b04893c73c50553070682799220080.tar.xz | |
all: split the merchant into DefaultMerchant and PaymentMerchant
The PaymentMerchant will be used if the payment method during inquiry
exist as the key in it; otherwise it will use DefaultMerchant
| -rw-r--r-- | client_options.go | 61 | ||||
| -rw-r--r-- | client_options_test.go | 56 | ||||
| -rw-r--r-- | merchant.go | 27 | ||||
| -rw-r--r-- | payment_method.go | 6 | ||||
| -rw-r--r-- | testdata/client_options_test.txt | 39 |
5 files changed, 162 insertions, 27 deletions
diff --git a/client_options.go b/client_options.go index b365ac0..fa6ad1c 100644 --- a/client_options.go +++ b/client_options.go @@ -18,30 +18,12 @@ type ClientOptions struct { // The hostname extracted from ServerUrl. host string - // The merchant code is the project code obtained from the Duitku - // merchant page. - // This code is useful as an identifier of your project in each - // request using the /merchant/* APIs. - // You can get this code on every project you register on the - // [merchant portal]. - // - // [merchant portal]: https://passport.duitku.com/merchant/Project - MerchantCode string `ini:"duitku::merchant_code"` + // DefaultMerchant default merchant to be used for payment. + DefaultMerchant Merchant `ini:"default-merchant"` - // MerchantApiKey The API key for signing merchant related request. - MerchantApiKey string `ini:"duitku::merchant_api_key"` - - // MerchantCallbackUrl The URL that will be used by Duitku to - // confirm payments made by your customers. - MerchantCallbackUrl string `ini:"duitku::merchant_callback_url"` - - // MerchantReturnUrl The URL that Duitku will direct the customer - // after the transaction is successful or canceled. - MerchantReturnUrl string `ini:"duitku::merchant_return_url"` - - // Merchant code and API key for payment through Indomaret. - IndomaretMerchantCode string `ini:"duitku::indomaret_merchant_code"` - IndomaretApiKey string `ini:"duitku::indomaret_api_key"` + // PaymentMerchant specific merchant to be used based on payment + // method. + PaymentMerchant map[string]Merchant `ini:"merchant"` // DisburseApiKey API key for signing disbursement request. DisburseApiKey string `ini:"duitku::disburse_api_key"` @@ -74,8 +56,23 @@ func LoadClientOptions(file string) (opts *ClientOptions, err error) { return opts, nil } -// validate each field values. -func (opts *ClientOptions) validate() (err error) { +// Merchant return the PaymentMerchant based on paymentMethod. +// If no key found, it will return DefaultMerchant. +func (opts *ClientOptions) Merchant(paymentMethod string) (merchant Merchant) { + var ( + found bool + ) + + merchant, found = opts.PaymentMerchant[paymentMethod] + if !found { + merchant = opts.DefaultMerchant + } + + return merchant +} + +// initAndValidate each field values. +func (opts *ClientOptions) initAndValidate() (err error) { var ( urlServer *url.URL ) @@ -96,5 +93,19 @@ func (opts *ClientOptions) validate() (err error) { return fmt.Errorf(`invalid or empty DisburseApiKey: %s`, opts.DisburseApiKey) } + var ( + method string + merchant Merchant + ) + for method, merchant = range opts.PaymentMerchant { + if len(merchant.CallbackUrl) == 0 { + merchant.CallbackUrl = opts.DefaultMerchant.CallbackUrl + } + if len(merchant.ReturnUrl) == 0 { + merchant.ReturnUrl = opts.DefaultMerchant.ReturnUrl + } + opts.PaymentMerchant[method] = merchant + } + return nil } diff --git a/client_options_test.go b/client_options_test.go new file mode 100644 index 0000000..0d865f3 --- /dev/null +++ b/client_options_test.go @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: 2023 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later + +package duitku + +import ( + "encoding/json" + "testing" + + "github.com/shuLhan/share/lib/ini" + "github.com/shuLhan/share/lib/test" +) + +func TestLoadClientOptions(t *testing.T) { + var ( + tdata *test.Data + err error + ) + + tdata, err = test.LoadData(`testdata/client_options_test.txt`) + if err != nil { + t.Fatal(err) + } + + var ( + opts ClientOptions + tag string + data []byte + ) + + data = tdata.Input[`all.conf`] + + err = ini.Unmarshal(data, &opts) + if err != nil { + t.Fatal(err) + } + + err = opts.initAndValidate() + if err != nil { + t.Fatal(err) + } + + var ( + exp []byte + got []byte + ) + + got, err = json.MarshalIndent(&opts, ``, ` `) + if err != nil { + t.Fatal(err) + } + + tag = `all.json` + exp = tdata.Output[tag] + test.Assert(t, tag, string(exp), string(got)) +} diff --git a/merchant.go b/merchant.go new file mode 100644 index 0000000..7d7d2c5 --- /dev/null +++ b/merchant.go @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2023 M. Shulhan <ms@kilabit.info> +// SPDX-License-Identifier: GPL-3.0-or-later + +package duitku + +type Merchant struct { + // The merchant code is the project code obtained from the Duitku + // merchant page. + // This code is useful as an identifier of your project in each + // request using the /merchant/* APIs. + // You can get this code on every project you register on the + // [merchant portal]. + // + // [merchant portal]: https://passport.duitku.com/merchant/Project + Code string `ini:"::code"` + + // The API key for signing merchant request. + ApiKey string `ini:"::api_key"` + + // The URL that will be used by Duitku to confirm payments made by + // your customers. + CallbackUrl string `ini:"::callback_url"` + + // The URL that Duitku will direct the customer after the transaction + // is successful or canceled. + ReturnUrl string `ini:"::return_url"` +} diff --git a/payment_method.go b/payment_method.go index b5e95fa..9dffcda 100644 --- a/payment_method.go +++ b/payment_method.go @@ -45,19 +45,21 @@ func (req *PaymentMethod) SetDateTime(t time.Time) { // Signature. func (req *PaymentMethod) Sign(opts ClientOptions) { var ( + merchant = opts.DefaultMerchant + plain string hash [sha256.Size]byte ) if len(req.MerchantCode) == 0 { - req.MerchantCode = opts.MerchantCode + req.MerchantCode = merchant.Code } if len(req.DateTime) == 0 { req.SetDateTime(time.Now()) } - plain = fmt.Sprintf(`%s%d%s%s`, req.MerchantCode, req.Amount, req.DateTime, opts.MerchantApiKey) + plain = fmt.Sprintf(`%s%d%s%s`, req.MerchantCode, req.Amount, req.DateTime, merchant.ApiKey) hash = sha256.Sum256([]byte(plain)) req.Signature = hex.EncodeToString(hash[:]) diff --git a/testdata/client_options_test.txt b/testdata/client_options_test.txt new file mode 100644 index 0000000..5d4d34e --- /dev/null +++ b/testdata/client_options_test.txt @@ -0,0 +1,39 @@ +>>> all.conf +[duitku] +server_url = https://sandbox.duitku.com +disburse_user_id = 1111 +disburse_email = my@company.com +disburse_api_key = abcd + +[default-merchant] +code = DXXXX +api_key = d3f4ult +callback_url = https://example.com/callback +return_url = https://example.com/payment + +## Payment using Indomaret use this merchant. +[merchant "IR"] +code = DYYYY +api_key = 1ndom4r3t + +<<< all.json +{ + "ServerUrl": "https://sandbox.duitku.com", + "DefaultMerchant": { + "Code": "DXXXX", + "ApiKey": "d3f4ult", + "CallbackUrl": "https://example.com/callback", + "ReturnUrl": "https://example.com/payment" + }, + "PaymentMerchant": { + "IR": { + "Code": "DYYYY", + "ApiKey": "1ndom4r3t", + "CallbackUrl": "https://example.com/callback", + "ReturnUrl": "https://example.com/payment" + } + }, + "DisburseApiKey": "abcd", + "DisburseEmail": "my@company.com", + "DisburseUserID": 1111 +} |
