mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 18:54:03 +08:00
Add Notify() to payment provider.
This commit is contained in:
parent
5de417ecf7
commit
4dca3bd3f7
@ -21,7 +21,6 @@ import (
|
|||||||
"github.com/astaxie/beego/utils/pagination"
|
"github.com/astaxie/beego/utils/pagination"
|
||||||
"github.com/casdoor/casdoor/object"
|
"github.com/casdoor/casdoor/object"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/go-pay/gopay/alipay"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetPayments
|
// GetPayments
|
||||||
@ -142,14 +141,16 @@ func (c *ApiController) DeletePayment() {
|
|||||||
// @Success 200 {object} controllers.Response The Response object
|
// @Success 200 {object} controllers.Response The Response object
|
||||||
// @router /notify-payment [post]
|
// @router /notify-payment [post]
|
||||||
func (c *ApiController) NotifyPayment() {
|
func (c *ApiController) NotifyPayment() {
|
||||||
bm, err := alipay.ParseNotifyToBodyMap(c.Ctx.Request)
|
owner := c.Ctx.Input.Param(":owner")
|
||||||
if err != nil {
|
providerName := c.Ctx.Input.Param(":provider")
|
||||||
panic(err)
|
productName := c.Ctx.Input.Param(":product")
|
||||||
}
|
paymentName := c.Ctx.Input.Param(":payment")
|
||||||
|
|
||||||
ok := object.NotifyPayment(bm)
|
body := c.Ctx.Input.RequestBody
|
||||||
|
|
||||||
|
ok := object.NotifyPayment(c.Ctx.Request, body, owner, providerName, productName, paymentName)
|
||||||
if ok {
|
if ok {
|
||||||
_, err = c.Ctx.ResponseWriter.Write([]byte("success"))
|
_, err := c.Ctx.ResponseWriter.Write([]byte("success"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -119,13 +119,13 @@ func (c *ApiController) DeleteProduct() {
|
|||||||
// @Title BuyProduct
|
// @Title BuyProduct
|
||||||
// @Tag Product API
|
// @Tag Product API
|
||||||
// @Description buy product
|
// @Description buy product
|
||||||
// @Param id query string true "The id of the product"
|
// @Param id query string true "The id of the product"
|
||||||
// @Param providerId query string true "The id of the provider"
|
// @Param providerName query string true "The name of the provider"
|
||||||
// @Success 200 {object} controllers.Response The Response object
|
// @Success 200 {object} controllers.Response The Response object
|
||||||
// @router /buy-product [post]
|
// @router /buy-product [post]
|
||||||
func (c *ApiController) BuyProduct() {
|
func (c *ApiController) BuyProduct() {
|
||||||
id := c.Input().Get("id")
|
id := c.Input().Get("id")
|
||||||
providerId := c.Input().Get("providerId")
|
providerName := c.Input().Get("providerName")
|
||||||
host := c.Ctx.Request.Host
|
host := c.Ctx.Request.Host
|
||||||
|
|
||||||
userId := c.GetSessionUsername()
|
userId := c.GetSessionUsername()
|
||||||
@ -140,7 +140,7 @@ func (c *ApiController) BuyProduct() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
payUrl, err := object.BuyProduct(id, providerId, user, host)
|
payUrl, err := object.BuyProduct(id, providerName, user, host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.ResponseError(err.Error())
|
c.ResponseError(err.Error())
|
||||||
return
|
return
|
||||||
|
@ -16,10 +16,9 @@ package object
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/go-pay/gopay"
|
|
||||||
"github.com/go-pay/gopay/alipay"
|
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,12 +28,12 @@ type Payment struct {
|
|||||||
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
CreatedTime string `xorm:"varchar(100)" json:"createdTime"`
|
||||||
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
DisplayName string `xorm:"varchar(100)" json:"displayName"`
|
||||||
|
|
||||||
Provider string `xorm:"varchar(100)" json:"provider"`
|
Provider string `xorm:"varchar(100)" json:"provider"`
|
||||||
Type string `xorm:"varchar(100)" json:"type"`
|
Type string `xorm:"varchar(100)" json:"type"`
|
||||||
Organization string `xorm:"varchar(100)" json:"organization"`
|
Organization string `xorm:"varchar(100)" json:"organization"`
|
||||||
User string `xorm:"varchar(100)" json:"user"`
|
User string `xorm:"varchar(100)" json:"user"`
|
||||||
ProductId string `xorm:"varchar(100)" json:"productId"`
|
ProductName string `xorm:"varchar(100)" json:"productName"`
|
||||||
ProductName string `xorm:"varchar(100)" json:"productName"`
|
ProductDisplayName string `xorm:"varchar(100)" json:"productDisplayName"`
|
||||||
|
|
||||||
Detail string `xorm:"varchar(100)" json:"detail"`
|
Detail string `xorm:"varchar(100)" json:"detail"`
|
||||||
Tag string `xorm:"varchar(100)" json:"tag"`
|
Tag string `xorm:"varchar(100)" json:"tag"`
|
||||||
@ -143,57 +142,45 @@ func DeletePayment(payment *Payment) bool {
|
|||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func notifyPayment(bm gopay.BodyMap) (*Payment, error) {
|
func notifyPayment(request *http.Request, body []byte, owner string, providerName string, productName string, paymentName string) (*Payment, error) {
|
||||||
owner := "admin"
|
payment := getPayment(owner, paymentName)
|
||||||
productName := bm.Get("subject")
|
if payment == nil {
|
||||||
paymentId := bm.Get("out_trade_no")
|
return nil, fmt.Errorf("the payment: %s does not exist", paymentName)
|
||||||
priceString := bm.Get("total_amount")
|
|
||||||
price := util.ParseFloat(priceString)
|
|
||||||
productId := bm.Get("productId")
|
|
||||||
providerId := bm.Get("providerId")
|
|
||||||
|
|
||||||
product := getProduct(owner, productId)
|
|
||||||
if product == nil {
|
|
||||||
return nil, fmt.Errorf("the product: %s does not exist", productId)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if productName != product.DisplayName {
|
product := getProduct(owner, productName)
|
||||||
return nil, fmt.Errorf("the payment's product name: %s doesn't equal to the expected product name: %s", productName, product.DisplayName)
|
if product == nil {
|
||||||
|
return nil, fmt.Errorf("the product: %s does not exist", productName)
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := product.getProvider(providerName)
|
||||||
|
if err != nil {
|
||||||
|
return payment, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pProvider, cert, err := provider.getPaymentProvider()
|
||||||
|
if err != nil {
|
||||||
|
return payment, err
|
||||||
|
}
|
||||||
|
|
||||||
|
productDisplayName, paymentName, price, productName, providerName, err := pProvider.Notify(request, body, cert.AuthorityPublicKey)
|
||||||
|
if err != nil {
|
||||||
|
return payment, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if productDisplayName != "" && productDisplayName != product.DisplayName {
|
||||||
|
return nil, fmt.Errorf("the payment's product name: %s doesn't equal to the expected product name: %s", productDisplayName, product.DisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if price != product.Price {
|
if price != product.Price {
|
||||||
return nil, fmt.Errorf("the payment's price: %f doesn't equal to the expected price: %f", price, product.Price)
|
return nil, fmt.Errorf("the payment's price: %f doesn't equal to the expected price: %f", price, product.Price)
|
||||||
}
|
}
|
||||||
|
|
||||||
payment := getPayment(owner, paymentId)
|
|
||||||
if payment == nil {
|
|
||||||
return nil, fmt.Errorf("the payment: %s does not exist", paymentId)
|
|
||||||
}
|
|
||||||
|
|
||||||
provider, err := product.getProvider(providerId)
|
|
||||||
if err != nil {
|
|
||||||
return payment, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cert := getCert(owner, provider.Cert)
|
|
||||||
if cert == nil {
|
|
||||||
return payment, fmt.Errorf("the cert: %s does not exist", provider.Cert)
|
|
||||||
}
|
|
||||||
|
|
||||||
ok, err := alipay.VerifySignWithCert(cert.AuthorityPublicKey, bm)
|
|
||||||
if err != nil {
|
|
||||||
return payment, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !ok {
|
|
||||||
return payment, fmt.Errorf("VerifySignWithCert() failed: %v", ok)
|
|
||||||
}
|
|
||||||
|
|
||||||
return payment, nil
|
return payment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NotifyPayment(bm gopay.BodyMap) bool {
|
func NotifyPayment(request *http.Request, body []byte, owner string, providerName string, productName string, paymentName string) bool {
|
||||||
payment, err := notifyPayment(bm)
|
payment, err := notifyPayment(request, body, owner, providerName, productName, paymentName)
|
||||||
|
|
||||||
if payment != nil {
|
if payment != nil {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -17,7 +17,6 @@ package object
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/pp"
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
@ -153,61 +152,54 @@ func (product *Product) getProvider(providerId string) (*Provider, error) {
|
|||||||
return provider, nil
|
return provider, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuyProduct(id string, providerId string, user *User, host string) (string, error) {
|
func BuyProduct(id string, providerName string, user *User, host string) (string, error) {
|
||||||
product := GetProduct(id)
|
product := GetProduct(id)
|
||||||
if product == nil {
|
if product == nil {
|
||||||
return "", fmt.Errorf("the product: %s does not exist", id)
|
return "", fmt.Errorf("the product: %s does not exist", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
provider, err := product.getProvider(providerId)
|
provider, err := product.getProvider(providerName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
cert := &Cert{}
|
pProvider, _, err := provider.getPaymentProvider()
|
||||||
if provider.Cert != "" {
|
if err != nil {
|
||||||
cert = getCert(product.Owner, provider.Cert)
|
return "", err
|
||||||
if cert == nil {
|
|
||||||
return "", fmt.Errorf("the cert: %s does not exist", provider.Cert)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pProvider := pp.GetPaymentProvider(provider.Type, provider.ClientId, provider.ClientSecret, provider.Host, cert.PublicKey, cert.PrivateKey, cert.AuthorityPublicKey, cert.AuthorityRootPublicKey)
|
owner := product.Owner
|
||||||
if pProvider == nil {
|
productName := product.Name
|
||||||
return "", fmt.Errorf("the payment provider type: %s is not supported", provider.Type)
|
paymentName := util.GenerateTimeId()
|
||||||
}
|
productDisplayName := product.DisplayName
|
||||||
|
|
||||||
paymentId := util.GenerateTimeId()
|
|
||||||
productName := product.DisplayName
|
|
||||||
productId := product.Name
|
|
||||||
|
|
||||||
originFrontend, originBackend := getOriginFromHost(host)
|
originFrontend, originBackend := getOriginFromHost(host)
|
||||||
returnUrl := fmt.Sprintf("%s/payments/%s/result", originFrontend, paymentId)
|
returnUrl := fmt.Sprintf("%s/payments/%s/result", originFrontend, paymentName)
|
||||||
notifyUrl := fmt.Sprintf("%s/api/notify-payment", originBackend)
|
notifyUrl := fmt.Sprintf("%s/api/notify-payment/%s/%s/%s/%s", originBackend, owner, providerName, productName, paymentName)
|
||||||
|
|
||||||
payUrl, err := pProvider.Pay(productName, productId, providerId, paymentId, product.Price, returnUrl, notifyUrl)
|
payUrl, err := pProvider.Pay(providerName, productName, paymentName, productDisplayName, product.Price, returnUrl, notifyUrl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
payment := Payment{
|
payment := Payment{
|
||||||
Owner: product.Owner,
|
Owner: product.Owner,
|
||||||
Name: paymentId,
|
Name: paymentName,
|
||||||
CreatedTime: util.GetCurrentTime(),
|
CreatedTime: util.GetCurrentTime(),
|
||||||
DisplayName: paymentId,
|
DisplayName: paymentName,
|
||||||
Provider: provider.Name,
|
Provider: provider.Name,
|
||||||
Type: provider.Type,
|
Type: provider.Type,
|
||||||
Organization: user.Owner,
|
Organization: user.Owner,
|
||||||
User: user.Name,
|
User: user.Name,
|
||||||
ProductId: productId,
|
ProductName: productName,
|
||||||
ProductName: productName,
|
ProductDisplayName: productDisplayName,
|
||||||
Detail: product.Detail,
|
Detail: product.Detail,
|
||||||
Tag: product.Tag,
|
Tag: product.Tag,
|
||||||
Currency: product.Currency,
|
Currency: product.Currency,
|
||||||
Price: product.Price,
|
Price: product.Price,
|
||||||
PayUrl: payUrl,
|
PayUrl: payUrl,
|
||||||
ReturnUrl: product.ReturnUrl,
|
ReturnUrl: product.ReturnUrl,
|
||||||
State: "Created",
|
State: "Created",
|
||||||
}
|
}
|
||||||
affected := AddPayment(&payment)
|
affected := AddPayment(&payment)
|
||||||
if !affected {
|
if !affected {
|
||||||
|
@ -17,6 +17,7 @@ package object
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/pp"
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
"xorm.io/core"
|
"xorm.io/core"
|
||||||
)
|
)
|
||||||
@ -182,6 +183,23 @@ func DeleteProvider(provider *Provider) bool {
|
|||||||
return affected != 0
|
return affected != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Provider) getPaymentProvider() (pp.PaymentProvider, *Cert, error) {
|
||||||
|
cert := &Cert{}
|
||||||
|
if p.Cert != "" {
|
||||||
|
cert = getCert(p.Owner, p.Cert)
|
||||||
|
if cert == nil {
|
||||||
|
return nil, nil, fmt.Errorf("the cert: %s does not exist", p.Cert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pProvider := pp.GetPaymentProvider(p.Type, p.ClientId, p.ClientSecret, p.Host, cert.PublicKey, cert.PrivateKey, cert.AuthorityPublicKey, cert.AuthorityRootPublicKey)
|
||||||
|
if pProvider == nil {
|
||||||
|
return nil, cert, fmt.Errorf("the payment provider type: %s is not supported", p.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return pProvider, cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Provider) GetId() string {
|
func (p *Provider) GetId() string {
|
||||||
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
return fmt.Sprintf("%s/%s", p.Owner, p.Name)
|
||||||
}
|
}
|
||||||
|
38
pp/alipay.go
38
pp/alipay.go
@ -16,7 +16,10 @@ package pp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
"github.com/go-pay/gopay"
|
"github.com/go-pay/gopay"
|
||||||
"github.com/go-pay/gopay/alipay"
|
"github.com/go-pay/gopay/alipay"
|
||||||
)
|
)
|
||||||
@ -42,19 +45,20 @@ func NewAlipayPaymentProvider(appId string, appPublicKey string, appPrivateKey s
|
|||||||
return pp
|
return pp
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *AlipayPaymentProvider) Pay(productName string, productId string, providerId string, paymentId string, price float64, returnUrl string, notifyUrl string) (string, error) {
|
func (pp *AlipayPaymentProvider) Pay(providerName string, productName string, paymentName string, productDisplayName string, price float64, returnUrl string, notifyUrl string) (string, error) {
|
||||||
//pp.Client.DebugSwitch = gopay.DebugOn
|
//pp.Client.DebugSwitch = gopay.DebugOn
|
||||||
|
|
||||||
bm := gopay.BodyMap{}
|
bm := gopay.BodyMap{}
|
||||||
|
|
||||||
|
bm.Set("providerName", providerName)
|
||||||
|
bm.Set("productName", productName)
|
||||||
|
|
||||||
bm.Set("return_url", returnUrl)
|
bm.Set("return_url", returnUrl)
|
||||||
bm.Set("notify_url", notifyUrl)
|
bm.Set("notify_url", notifyUrl)
|
||||||
|
|
||||||
bm.Set("subject", productName)
|
bm.Set("subject", productDisplayName)
|
||||||
bm.Set("out_trade_no", paymentId)
|
bm.Set("out_trade_no", paymentName)
|
||||||
bm.Set("total_amount", getPriceString(price))
|
bm.Set("total_amount", getPriceString(price))
|
||||||
bm.Set("productId", productId)
|
|
||||||
bm.Set("providerId", productId)
|
|
||||||
|
|
||||||
payUrl, err := pp.Client.TradePagePay(context.Background(), bm)
|
payUrl, err := pp.Client.TradePagePay(context.Background(), bm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -62,3 +66,27 @@ func (pp *AlipayPaymentProvider) Pay(productName string, productId string, provi
|
|||||||
}
|
}
|
||||||
return payUrl, nil
|
return payUrl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pp *AlipayPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string) (string, string, float64, string, string, error) {
|
||||||
|
bm, err := alipay.ParseNotifyToBodyMap(request)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", 0, "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
providerName := bm.Get("providerName")
|
||||||
|
productName := bm.Get("productName")
|
||||||
|
|
||||||
|
productDisplayName := bm.Get("subject")
|
||||||
|
paymentName := bm.Get("out_trade_no")
|
||||||
|
price := util.ParseFloat(bm.Get("total_amount"))
|
||||||
|
|
||||||
|
ok, err := alipay.VerifySignWithCert(authorityPublicKey, bm)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", 0, "", "", err
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return "", "", 0, "", "", fmt.Errorf("VerifySignWithCert() failed: %v", ok)
|
||||||
|
}
|
||||||
|
|
||||||
|
return productDisplayName, paymentName, price, productName, providerName, nil
|
||||||
|
}
|
||||||
|
60
pp/gc.go
60
pp/gc.go
@ -22,6 +22,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/casdoor/casdoor/util"
|
"github.com/casdoor/casdoor/util"
|
||||||
@ -52,6 +53,20 @@ type GcPayRespInfo struct {
|
|||||||
PayUrl string `json:"payurl"`
|
PayUrl string `json:"payurl"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GcNotifyRespInfo struct {
|
||||||
|
Xmpch string `json:"xmpch"`
|
||||||
|
OrderDate string `json:"orderdate"`
|
||||||
|
OrderNo string `json:"orderno"`
|
||||||
|
Amount float64 `json:"amount"`
|
||||||
|
Jylsh string `json:"jylsh"`
|
||||||
|
TradeNo string `json:"tradeno"`
|
||||||
|
PayMethod string `json:"paymethod"`
|
||||||
|
OrderState string `json:"orderstate"`
|
||||||
|
ReturnType string `json:"return_type"`
|
||||||
|
PayerId string `json:"payerid"`
|
||||||
|
PayerName string `json:"payername"`
|
||||||
|
}
|
||||||
|
|
||||||
type GcRequestBody struct {
|
type GcRequestBody struct {
|
||||||
Op string `json:"op"`
|
Op string `json:"op"`
|
||||||
Xmpch string `json:"xmpch"`
|
Xmpch string `json:"xmpch"`
|
||||||
@ -115,7 +130,7 @@ func (pp *GcPaymentProvider) doPost(postBytes []byte) ([]byte, error) {
|
|||||||
return respBytes, nil
|
return respBytes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pp *GcPaymentProvider) Pay(productName string, productId string, providerId string, paymentId string, price float64, returnUrl string, notifyUrl string) (string, error) {
|
func (pp *GcPaymentProvider) Pay(providerName string, productName string, paymentName string, productDisplayName string, price float64, returnUrl string, notifyUrl string) (string, error) {
|
||||||
payReqInfo := GcPayReqInfo{
|
payReqInfo := GcPayReqInfo{
|
||||||
OrderDate: util.GenerateSimpleTimeId(),
|
OrderDate: util.GenerateSimpleTimeId(),
|
||||||
OrderNo: util.GenerateTimeId(),
|
OrderNo: util.GenerateTimeId(),
|
||||||
@ -159,6 +174,10 @@ func (pp *GcPaymentProvider) Pay(productName string, productId string, providerI
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if respBody.ReturnCode != "SUCCESS" {
|
||||||
|
return "", fmt.Errorf("%s: %s", respBody.ReturnCode, respBody.ReturnMsg)
|
||||||
|
}
|
||||||
|
|
||||||
payRespInfoBytes, err := base64.StdEncoding.DecodeString(respBody.Data)
|
payRespInfoBytes, err := base64.StdEncoding.DecodeString(respBody.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -172,3 +191,42 @@ func (pp *GcPaymentProvider) Pay(productName string, productId string, providerI
|
|||||||
|
|
||||||
return payRespInfo.PayUrl, nil
|
return payRespInfo.PayUrl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pp *GcPaymentProvider) Notify(request *http.Request, body []byte, authorityPublicKey string) (string, string, float64, string, string, error) {
|
||||||
|
reqBody := GcRequestBody{}
|
||||||
|
m, err := url.ParseQuery(string(body))
|
||||||
|
if err != nil {
|
||||||
|
return "", "", 0, "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
reqBody.Op = m["op"][0]
|
||||||
|
reqBody.Xmpch = m["xmpch"][0]
|
||||||
|
reqBody.Version = m["version"][0]
|
||||||
|
reqBody.Data = m["data"][0]
|
||||||
|
reqBody.RequestTime = m["requesttime"][0]
|
||||||
|
reqBody.Sign = m["sign"][0]
|
||||||
|
|
||||||
|
notifyReqInfoBytes, err := base64.StdEncoding.DecodeString(reqBody.Data)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", 0, "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var notifyRespInfo GcNotifyRespInfo
|
||||||
|
err = json.Unmarshal(notifyReqInfoBytes, ¬ifyRespInfo)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", 0, "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
providerName := ""
|
||||||
|
productName := ""
|
||||||
|
|
||||||
|
productDisplayName := ""
|
||||||
|
paymentName := notifyRespInfo.OrderNo
|
||||||
|
price := notifyRespInfo.Amount
|
||||||
|
|
||||||
|
if notifyRespInfo.OrderState != "1" {
|
||||||
|
return "", "", 0, "", "", fmt.Errorf("error order state: %s", notifyRespInfo.OrderDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return productDisplayName, paymentName, price, productName, providerName, nil
|
||||||
|
}
|
||||||
|
@ -14,8 +14,11 @@
|
|||||||
|
|
||||||
package pp
|
package pp
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
type PaymentProvider interface {
|
type PaymentProvider interface {
|
||||||
Pay(productName string, productId string, providerId string, paymentId string, price float64, returnUrl string, notifyUrl string) (string, error)
|
Pay(providerName string, productName string, paymentName string, productDisplayName string, price float64, returnUrl string, notifyUrl string) (string, error)
|
||||||
|
Notify(request *http.Request, body []byte, authorityPublicKey string) (string, string, float64, string, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetPaymentProvider(typ string, appId string, clientSecret string, host string, appPublicKey string, appPrivateKey string, authorityPublicKey string, authorityRootPublicKey string) PaymentProvider {
|
func GetPaymentProvider(typ string, appId string, clientSecret string, host string, appPublicKey string, appPrivateKey string, authorityPublicKey string, authorityRootPublicKey string) PaymentProvider {
|
||||||
|
@ -164,7 +164,7 @@ func initAPI() {
|
|||||||
beego.Router("/api/update-payment", &controllers.ApiController{}, "POST:UpdatePayment")
|
beego.Router("/api/update-payment", &controllers.ApiController{}, "POST:UpdatePayment")
|
||||||
beego.Router("/api/add-payment", &controllers.ApiController{}, "POST:AddPayment")
|
beego.Router("/api/add-payment", &controllers.ApiController{}, "POST:AddPayment")
|
||||||
beego.Router("/api/delete-payment", &controllers.ApiController{}, "POST:DeletePayment")
|
beego.Router("/api/delete-payment", &controllers.ApiController{}, "POST:DeletePayment")
|
||||||
beego.Router("/api/notify-payment", &controllers.ApiController{}, "POST:NotifyPayment")
|
beego.Router("/api/notify-payment/?:owner/?:provider/?:product/?:payment", &controllers.ApiController{}, "POST:NotifyPayment")
|
||||||
|
|
||||||
beego.Router("/api/send-email", &controllers.ApiController{}, "POST:SendEmail")
|
beego.Router("/api/send-email", &controllers.ApiController{}, "POST:SendEmail")
|
||||||
beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms")
|
beego.Router("/api/send-sms", &controllers.ApiController{}, "POST:SendSms")
|
||||||
|
@ -34,8 +34,8 @@ class PaymentListPage extends BaseListPage {
|
|||||||
type: "PayPal",
|
type: "PayPal",
|
||||||
organization: "built-in",
|
organization: "built-in",
|
||||||
user: "admin",
|
user: "admin",
|
||||||
productId: "computer-1",
|
productName: "computer-1",
|
||||||
productName: "A notebook computer",
|
productDisplayName: "A notebook computer",
|
||||||
detail: "This is a computer with excellent CPU, memory and disk",
|
detail: "This is a computer with excellent CPU, memory and disk",
|
||||||
tag: "Promotion-1",
|
tag: "Promotion-1",
|
||||||
currency: "USD",
|
currency: "USD",
|
||||||
@ -172,11 +172,11 @@ class PaymentListPage extends BaseListPage {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("payment:Product"),
|
title: i18next.t("payment:Product"),
|
||||||
dataIndex: 'productName',
|
dataIndex: 'productDisplayName',
|
||||||
key: 'productName',
|
key: 'productDisplayName',
|
||||||
// width: '160px',
|
// width: '160px',
|
||||||
sorter: true,
|
sorter: true,
|
||||||
...this.getColumnSearchProps('productName'),
|
...this.getColumnSearchProps('productDisplayName'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: i18next.t("payment:Price"),
|
title: i18next.t("payment:Price"),
|
||||||
|
@ -60,7 +60,7 @@ class PaymentResultPage extends React.Component {
|
|||||||
}
|
}
|
||||||
<Result
|
<Result
|
||||||
status="success"
|
status="success"
|
||||||
title={`${i18next.t("payment:You have successfully completed the payment")}: ${payment.productName}`}
|
title={`${i18next.t("payment:You have successfully completed the payment")}: ${payment.productDisplayName}`}
|
||||||
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
|
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
|
||||||
extra={[
|
extra={[
|
||||||
<Button type="primary" key="returnUrl" onClick={() => {
|
<Button type="primary" key="returnUrl" onClick={() => {
|
||||||
@ -80,7 +80,7 @@ class PaymentResultPage extends React.Component {
|
|||||||
}
|
}
|
||||||
<Result
|
<Result
|
||||||
status="info"
|
status="info"
|
||||||
title={`${i18next.t("payment:The payment is still under processing")}: ${payment.productName}, ${i18next.t("payment:the current state is")}: ${payment.state}, ${i18next.t("payment:please wait for a few seconds...")}`}
|
title={`${i18next.t("payment:The payment is still under processing")}: ${payment.productDisplayName}, ${i18next.t("payment:the current state is")}: ${payment.state}, ${i18next.t("payment:please wait for a few seconds...")}`}
|
||||||
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
|
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
|
||||||
extra={[
|
extra={[
|
||||||
<Spin size="large" tip={i18next.t("payment:Processing...")} />,
|
<Spin size="large" tip={i18next.t("payment:Processing...")} />,
|
||||||
@ -96,7 +96,7 @@ class PaymentResultPage extends React.Component {
|
|||||||
}
|
}
|
||||||
<Result
|
<Result
|
||||||
status="error"
|
status="error"
|
||||||
title={`${i18next.t("payment:The payment has failed")}: ${payment.productName}, ${i18next.t("payment:the current state is")}: ${payment.state}`}
|
title={`${i18next.t("payment:The payment has failed")}: ${payment.productDisplayName}, ${i18next.t("payment:the current state is")}: ${payment.state}`}
|
||||||
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
|
subTitle={i18next.t("payment:Please click the below button to return to the original website")}
|
||||||
extra={[
|
extra={[
|
||||||
<Button type="primary" key="returnUrl" onClick={() => {
|
<Button type="primary" key="returnUrl" onClick={() => {
|
||||||
|
@ -56,7 +56,7 @@ export function deleteProduct(product) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function buyProduct(owner, name, providerId) {
|
export function buyProduct(owner, name, providerId) {
|
||||||
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerId=${providerId}`, {
|
return fetch(`${Setting.ServerUrl}/api/buy-product?id=${owner}/${encodeURIComponent(name)}&providerName=${providerId}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
credentials: 'include',
|
credentials: 'include',
|
||||||
}).then(res => res.json());
|
}).then(res => res.json());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user