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

Add rakuten pay api #9

Merged
merged 9 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
237 changes: 230 additions & 7 deletions gateways/paygent/paygent.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type Config struct {
CAFilePath string // this is required, if CAFileContent is blank
CAFileContent string // this is required, if CAFilePath is blank

ProductionMode bool
ProductionMode bool
SecurityCodeUse bool
}

Expand Down Expand Up @@ -188,7 +188,6 @@ func (paygent *Paygent) Request(telegramKind string, params gomerchant.Params) (
}

response, err = client.Post(serviceURL.String(), "application/x-www-form-urlencoded", strings.NewReader(urlValues.Encode()))

if err == nil {
if response.StatusCode == 200 {
defer response.Body.Close()
Expand Down Expand Up @@ -224,7 +223,6 @@ func (paygent *Paygent) Request(telegramKind string, params gomerchant.Params) (
err = errors.New("failed to process this request")
}
}

return results, err
}
}
Expand All @@ -243,7 +241,6 @@ func (paygent *Paygent) Authorize(amount uint64, params gomerchant.AuthorizePara
"trading_id": params.OrderID,
"payment_amount": amount,
"payment_class": 10,

}
)

Expand All @@ -257,18 +254,18 @@ func (paygent *Paygent) Authorize(amount uint64, params gomerchant.AuthorizePara

if paymentMethod := params.PaymentMethod; paymentMethod != nil {
if paygent.Config.SecurityCodeUse {
requestParams["security_code_use"]=1
requestParams["security_code_use"] = 1
}
if savedCreditCard := paymentMethod.SavedCreditCard; savedCreditCard != nil {
requestParams["stock_card_mode"] = 1
requestParams["customer_id"] = savedCreditCard.CustomerID
requestParams["customer_card_id"] = savedCreditCard.CreditCardID
requestParams["card_conf_number"]=savedCreditCard.CVC
requestParams["card_conf_number"] = savedCreditCard.CVC

} else if creditCard := paymentMethod.CreditCard; creditCard != nil {
requestParams["card_number"] = creditCard.Number
requestParams["card_valid_term"] = getValidTerm(creditCard)
requestParams["card_conf_number"]=creditCard.CVC
requestParams["card_conf_number"] = creditCard.CVC

} else {
return response, gomerchant.ErrNotSupportedPaymentMethod
Expand Down Expand Up @@ -365,3 +362,229 @@ func (paygent *Paygent) Query(transactionID string) (gomerchant.Transaction, err
transaction.Params = results.Params
return transaction, err
}

func (paygent *Paygent) InquiryNotification(noticeID string) (response gomerchant.InquiryResponse, err error) {
reqParam := gomerchant.Params{}
if len(noticeID) != 0 {
reqParam["payment_notice_id"] = noticeID
}
results, err := paygent.Request("091", reqParam)
lily1110 marked this conversation as resolved.
Show resolved Hide resolved
response.Params = results.Params
lily1110 marked this conversation as resolved.
Show resolved Hide resolved
if paymentID, ok := getPaymentID(results); ok {
response.TransactionID = paymentID
if tradingID, ok := results.Get("trading_id"); ok {
response.TradingID = fmt.Sprint(tradingID)
}

if paymentNoticeID, ok := results.Get("payment_notice_id"); ok {
response.PaymentNoticeID = fmt.Sprint(paymentNoticeID)
}

if paymentInitDate, ok := results.Get("payment_init_date"); ok {
response.PaymentInitDate = fmt.Sprint(paymentInitDate)
}

if paymentChangeDate, ok := results.Get("change_date"); ok {
response.PaymentChangeDate = fmt.Sprint(paymentChangeDate)
}

if paymentAmount, ok := results.Get("payment_amount"); ok {
response.PaymentAmount = fmt.Sprint(paymentAmount)
}

if basePaymentID, ok := results.Get("base_payment_id"); ok {
response.BasePaymentID = fmt.Sprint(basePaymentID)
}

if paymentStatus, ok := results.Get("payment_status"); ok {
response.PaymentStatus = fmt.Sprint(paymentStatus)
}
}

if successCode, ok := results.Get("success_code"); ok {
response.SuccessCode = fmt.Sprint(successCode)
}

if successDetail, ok := results.Get("success_detail"); ok {
response.SuccessDetail = fmt.Sprint(successDetail)
}
return response, err
}

// This is rakuten pay authorize function
// Before user confirmed on rakuten page status is 10:already applid
// After user confirmed status change to 20: Authorization OK
func (paygent *Paygent) RakutePayApplicationMessage(amount uint64, params gomerchant.ApplicationParams) (gomerchant.ApplicationResponse, error) {
var (
requestParams = gomerchant.Params{
"payment_amount": amount,
"merchandise_type": params.MerchandiseType,
"pc_mobile_type": params.PCMobileType,
"button_type": params.ButtonType,
"return_url": params.ReturnUrl,
"cancel_url": params.CancelUrl,
}
)

for i, g := range params.Goods {
requestParams[fmt.Sprintf("goods[%d]", i)] = g.Name
requestParams[fmt.Sprintf("goods_id[%d]", i)] = g.ID
requestParams[fmt.Sprintf("goods_price[%d]", i)] = g.Price
requestParams[fmt.Sprintf("goods_amount[%d]", i)] = g.Amount
}
var res gomerchant.ApplicationResponse
results, err := paygent.Request("270", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
res.TransactionID = fmt.Sprint(paymentID)
}

if tradeGenerationDate, ok := results.Get("trade_generation_date"); ok {
res.TradeGenerationDate = fmt.Sprint(tradeGenerationDate)
}

//Rakuten pay reponse redirect_html can not be find, so here need to do more logic
redirectHTML := strings.Split(results.RawBody, "redirect_html=")
if len(redirectHTML) == 2 {
res.RedirectHTML = redirectHTML[1]

}
return res, nil
}
return res, err
}

// This is rakuten pay capture function
func (paygent *Paygent) RakutenPaySalesMessage(transactionID string) (gomerchant.CaptureResponse, error) {
var (
response gomerchant.CaptureResponse
requestParams = gomerchant.Params{
"payment_id": transactionID,
}
)

results, err := paygent.Request("271", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
response.TransactionID = fmt.Sprint(paymentID)
}
}
response.Params = results.Params
return response, err
}

// This is rakuten pay void function
func (paygent *Paygent) RakutenPayCancellationMessage(transactionID string) (gomerchant.VoidResponse, error) {
var (
response gomerchant.VoidResponse
requestParams = gomerchant.Params{
"payment_id": transactionID,
}
)

results, err := paygent.Request("272", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
response.TransactionID = fmt.Sprint(paymentID)
}
}
response.Params = results.Params
return response, err
}

func (paygent *Paygent) RakutenPayCorrectionMessage(transactionID string, amount uint) (gomerchant.RefundResponse, error) {
var (
response gomerchant.RefundResponse
requestParams = gomerchant.Params{
"payment_id": transactionID,
"payment_amount": amount,
//Because it's hard to specify every item price in our system
//Like order with discount, it's so hard to calculate every item price and need equals total amounts.
//So we set whole order as a goods to rakuten pay
//If we could fix this problem later. Should be care with `del_flg`. Please read the documentation carefully [https://theplanttokyo.atlassian.net/browse/LAX-3319]
"goods_id[0]": gomerchant.RAKUTEN_PAY_PRODUCT_ID,
"goods_price[0]": amount,
"goods_amount[0]": 1,
}
)

results, err := paygent.Request("273", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
response.TransactionID = fmt.Sprint(paymentID)
}
}
response.Params = results.Params
return response, err
}

// Paypay authrioze function
func (paygent *Paygent) PayPayApplicationMessage(amount uint64, params gomerchant.ApplicationParams) (gomerchant.ApplicationResponse, error) {
var (
requestParams = gomerchant.Params{
"payment_amount": amount,
"return_url": params.ReturnUrl,
"cancel_url": params.CancelUrl,
}
)
var res gomerchant.ApplicationResponse
results, err := paygent.Request("420", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
res.TransactionID = fmt.Sprint(paymentID)
}

if tradeGenerationDate, ok := results.Get("trade_generation_date"); ok {
res.TradeGenerationDate = fmt.Sprint(tradeGenerationDate)
}

//Rakuten pay reponse redirect_html can not be find, so here need to do more logic
redirectHTML := strings.Split(results.RawBody, "redirect_html=")
if len(redirectHTML) == 2 {
res.RedirectHTML = redirectHTML[1]

}
return res, nil
}
return res, err
}

func (paygent *Paygent) PayPaySalesMessage(transactionID string) (gomerchant.CaptureResponse, error) {
var (
response gomerchant.CaptureResponse
requestParams = gomerchant.Params{
"payment_id": transactionID,
}
)

results, err := paygent.Request("422", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
response.TransactionID = fmt.Sprint(paymentID)
}
}
response.Params = results.Params
return response, err
}

func (paygent *Paygent) PayPayCancelAndRefundMessage(transactionID string, amount uint) (gomerchant.RefundResponse, error) {
var (
response gomerchant.RefundResponse
requestParams = gomerchant.Params{
"payment_id": transactionID,
}
)

if amount > 0 {
requestParams["repayment_amount"] = amount
}

results, err := paygent.Request("421", requestParams)
if err == nil {
if paymentID, ok := results.Get("payment_id"); ok {
response.TransactionID = fmt.Sprint(paymentID)
}
}
response.Params = results.Params
return response, err
}
9 changes: 9 additions & 0 deletions gateways/paygent/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,13 @@ var TelegramServiceURLs = map[string]string{
"13": "/n/paypal/request",
// ###電子マネー決済URL###
"15": "/n/emoney/request",
//rakuten pay
"270": "/n/rakutenid/request",
"271": "/n/rakutenid/request",
"272": "/n/rakutenid/request",
"273": "/n/rakutenid/request",
//pay pay
"420": "/n/paypay/request",
"421": "/n/paypay/request",
"422": "/n/paypay/request",
}
16 changes: 16 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module github.com/qor/gomerchant

go 1.21

require (
github.com/jinzhu/configor v1.2.1
github.com/stripe/stripe-go v70.15.0+incompatible
golang.org/x/text v0.8.0
)

require (
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/stretchr/testify v1.8.2 // indirect
golang.org/x/net v0.8.0 // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
)
29 changes: 29 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jinzhu/configor v1.2.1 h1:OKk9dsR8i6HPOCZR8BcMtcEImAFjIhbJFZNyn5GCZko=
github.com/jinzhu/configor v1.2.1/go.mod h1:nX89/MOmDba7ZX7GCyU/VIaQ2Ar2aizBl2d3JLF/rDc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stripe/stripe-go v70.15.0+incompatible h1:hNML7M1zx8RgtepEMlxyu/FpVPrP7KZm1gPFQquJQvM=
github.com/stripe/stripe-go v70.15.0+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8axYZkSN/uA/T/A64pfKdBAMiY=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
41 changes: 41 additions & 0 deletions payment_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,44 @@ type VoidResponse struct {
TransactionID string
Params
}

type InquiryResponse struct {
TransactionID string
TradingID string
PaymentNoticeID string
PaymentInitDate string
PaymentChangeDate string
PaymentAmount string
BasePaymentID string
PaymentStatus string
SuccessCode string
SuccessDetail string
Params
}

type ApplicationParams struct {
MerchandiseType uint64
PCMobileType uint64
ButtonType string
ReturnUrl string
CancelUrl string
Goods []Good
Params
}

type ApplicationResponse struct {
TransactionID string
OrderCode string
TradeGenerationDate string
RedirectHTML string
Params
}

type Good struct {
ID string
Name string
Price float64
Amount uint64
}

const RAKUTEN_PAY_PRODUCT_ID = "WholeOrderAmount"
Loading