Skip to content

Laysi/go-ecpay-sdk

Repository files navigation

ECPay SDK for Golang

license go-version latest-version test-ci stability-wip

Description

ECPay SDK for Golang,with some helpers package.

Feature

  • Configure
    • Merchant ID
    • Hash Key
    • Hash IV
    • Return URL
    • Period Return Url
  • API
    • AioCheckOut Query Builder
    • QueryCreditCardPeriodInfo
    • QueryTradeInfo
  • Gin CheckMacValue Validator Handler
  • Echo CheckMacValue Validator Handler
  • Predefined Model
  • OpenAPI Definition

Init client

import (
	"github.com/Laysi/go-ecpay-sdk"
	"github.com/Laysi/go-ecpay-sdk/base"
)

for production

client := ecpay.NewClient("<MERCHANT_ID>", "<HASH_KEY>", "<HASH_IV>", "<RETURN_URL>")

for staging

client := ecpay.NewStageClient(ecpay.WithReturnURL("<RETURN_URL>"))

options

client = ecpay.NewStageClient(
    ecpay.WithReturnURL("<RETURN_URL>"), 
    ecpay.WithPeriodReturnURL("<PERIOD_RETURN_URL>"),
    ecpay.WithClientBackURL("<CLIENT_BACK_URL>"),
    ecpay.WithClientRedirectURL("<CLIENT_REDIRECT_URL>"),
    ecpay.WithOrderResultURL("<ORDER_RESULT_URL>"),
    ecpay.WithPaymentInfoURL("<PAYMENT_INFO_URL>"),
    ecpay.WithPlatformID("<PLATFORM_ID>"),
    ecpay.WithCtxFunc(func(c context.Context) context.Context {
        return context.WithValue(c, "<KEY>", "<VALUE>") // Add context operation for every request pass to the api client
    }),
    ecpay.WithDebug,  // Turn on debug log
)

Usage

Create Order

html, err := client.CreateOrder("<MerchantTradeNo>", time.Now(), 1000, "<Description>", []string{"<ItemName1>", "<ItemName2>"}).
    WithOptional(ecpay.AioCheckOutGeneralOptional{
        StoreID:           "<StoreID>",
        ItemURL:           "<ItemURL>",
        Remark:            "<Remark>",
        ChooseSubPayment:  ecpayBase.CHOOSESUBPAYMENTENUM_EMPTY,
        NeedExtraPaidInfo: ecpayBase.NEEDEXTRAPAIDINFOENUM_N,
        PlatformID:        "<PlatformID>",
        CustomField1:      "<CustomField1>",
        CustomField2:      "<CustomField2>",
        CustomField3:      "<CustomField3>",
        CustomField4:      "<CustomField4>",
        Language:          ecpayBase.LANGUAGEENUM_ENG,
    }).
    SetAllPayment(ecpayBase.CHOOSEPAYMENTENUM_ATM, ecpayBase.CHOOSEPAYMENTENUM_CREDIT).
    WithCreditOptional(ecpay.AioCheckOutCreditOptional{
        BindingCard:      ecpayBase.BINDINGCARDENUM_BINDING,
        MerchantMemberID: "<MerchantMemberID>",
    }).
    WithCreditOnetimeOptional(ecpay.AioCheckOutCreditOnetimeOptional{
        Redeem:   ecpayBase.REDEEMENUM_Y,
        UnionPay: ecpayBase.UNIONPAYENUM_HIDDEN,
    }).
    WithCreditInstallmentOptional(3, 12, 18).
    WithCreditPeriodOptional(ecpayBase.CREDITPERIODTYPEENUM_DAY, 1, 0).
    WithAtmOptional(5).
    WithCvsBarcodeOptional(ecpay.AioCheckOutCvsBarcodeOptional{
        StoreExpireDate: 5,
        Desc1:           "<Desc1>",
        Desc2:           "<Desc1>",
        Desc3:           "<Desc1>",
        Desc4:           "<Desc1>",
    }).
    GenerateRequestHtml()

QueryCreditCardPeriodInfo

info, resp, err := client.QueryCreditCardPeriodInfo("<MerchantTradeNo>", time.Now())

QueryTradeInfo

info, resp, err := client.QueryTradeInfo("<MerchantTradeNo>", time.Now())

Echo Helper

Check Mac Validator Handler

This handler can use to check the data CheckMacValue from the ECPAY server,and will return 0|Error with 400 status if validating failed.

server := echo.New()
var ecpayClient = ecpay.NewStageClient(ecpay.WithReturnURL("<RETURN_URL>"))
server.POST("/ecpay/return", func(c echo.Context) error { ... },ecpayEcho.ECPayCheckMacValueHandler(ecpayClient))

Gin Helper

Check Mac Validator Handler

This handler can use to check the data CheckMacValue from the ECPAY server,and will return 0|Error with 400 status if validating failed.

server := gin.Default()
var ecpayClient = ecpay.NewStageClient(ecpay.WithReturnURL("<RETURN_URL>"))
server.POST("/ecpay/return",ecpayGin.ECPayCheckMacValueHandler(ecpayClient), func(c *gin.Context) {...})

Ecpay Data Binding Patch Helper

Due to gin-gonic/gin#2510,there have some bug to binding the datetime field of data from ecpay server in gin's current version. So there is a helper function to deal with it as a temporary workaround.

server := gin.Default()
server.POST("/ecpay/return",ecpayCheckMacValueHandler, func(c *gin.Context) {
    data := ecpayBase.OrderResult{}
    err := ecpayGin.ResponseBodyDateTimePatchHelper(c)
    if err != nil {
        fmt.Println(err.Error())
        c.Status(http.StatusInternalServerError)
        return
    }
    if err = c.MustBindWith(&data, binding.FormPost); err != nil {
        fmt.Println(err.Error())
        return
    }
})

server.POST("/ecpay/period",ecpayCheckMacValueHandler, func(c *gin.Context) {
    data := ecpayBase.PeriodOrderResult{}
    err := ecpayGin.ResponseBodyDateTimePatchHelper(c)

    if err != nil {
        fmt.Println(err.Error())
        c.Status(http.StatusInternalServerError)
        return
    }
    if err := c.MustBindWith(&data, binding.FormPost); err != nil {
        fmt.Println(err.Error())
        return
    }
})