You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
12 KiB

package alipay
import (
"bkb-payment/pkg/util"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"fmt"
"net/url"
"time"
)
const (
baseurl = "https://open-sea-global.alipay.com"
//privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCuAk8Mon2DT/pMIkItbX9h4+qlzwiFTb4wtB8uPP77x/4Z9rZdtveviFmsgb1DGaNMjGPJ884QB2dY+TclYmaGhZ9ZeICRyLEtptr8atoW1jno+1a60DH9CUEE9wm5Vf+eJ5N+89XDD6eT8WjaQyVWgz1jAJNrpGCSZRSKa6ryGZWMZFx2Rx8k/JEgWJJJyo1OXnlF9G+MQE69/2m8NQx+5GIyAwnT1y0yK9Y0CDAC4kzvuZf7COTYz5ic7MqQ9C1l0mLD2SfJTOzAcSMhAny1GV9j+B7p69ejBk5xHZ7rHOTJLlO2TOOt/zWNt3JvclFfWVQeF5vr+j0CRpcgZ34pAgMBAAECggEAU37qHX7uyQ6cZOHfbVroT7mEg5FnXkeipk4X1CESnRAm/qBie29rREAh/2O1xDfOItIOo/4n94sF7SyQaJDh71S41L68urdZRTWWSJ6hDWo4GXJY+IUkJ23EVDSR5uu8H1CQNs+b1+BwIc4p6OllRjDtSM8i7fjPGhAEnjLxsP8I1hZRL6jdIAqLjQYYVrsxbKwe20ptpiLoPdXlagw4nJ4FHX5eUL3JcnJyYEEO33rQAbCB4v/oq0tTPk5Qy+xq59dxSGHmRVWdl/2lGjkynom4WVwkLl5Pq7+pQvRPQq+Jy28wcde44XVjxuZUofimDui/ROxSQUw5ZoPC+l/+XQKBgQDgPsoVlpTCmCkV7XW2ZZhSTtVt2jC57KeTX+WVzn9Nx1L5LPYZm/a7YwGDdV/rBCe7M4IgMN3WjzSpsAUiZTDeGwpRQQWsZR/Ao3k+IRYm0pgzoj1QhvnWDvULB/0oHzSQ9yKntoiCJQngl87Tky0fentXO1aM5kWB2aoxOrnY6wKBgQDGpmI3x/uGCSlR5X7fRWyW+QKc/UCe3ZmCpTmTEGZ9dnIQCbP8l1mNTGTwBFqyKD2dL2DyueWJfr1OmQK5Th1nb22TWSLdVozE1/t1mot6nAtRt1Jp8VBOuBAVNRAAeMS1Qau148cxGLI1xXJCRA/Ksr0IbH1Z50OaPWaiCheAOwKBgFSOWJUbWqylw5hJGgHU/ULMBx6ND6KL4gRoPKHoY4hoiJj8oy+056xxALkZITn1LyYfngmVY5DsHud9P/JgRbT6bUGGSyVeXEK/YZBT2Y56CnotywD6ZGqa6Ttnn8XpPmELTz3+TisE3Fyb4ZlV/cXI4YlbDp/ClKMJ+GrnwfxRAoGAbbLuJD20gXVHsykX4fY1nD2Qmt8js1dOcZ4KaFMzNe+V15N0KHXwBx570yukZiPguo+yavgLcN1jbycCIRCpHjijey5LGY21GPLosy4P/jpz6cFhqo2POplckEmIN6p5flrwlvZdRpiLuTP6/+sUCWyhBSjcJCyY4XEs3yjRh4cCgYBpBngm/5a+UglZs9TAk67+yPJmcNx4n2Hum7g+JpY6SZuF7cvEPGQfVX4A7kaEGDcs0nQ2ZJRZHNk/HMIm5QYADOK2Tn2sUJIOw1SXQN53wR5/+YRT8YfyOeIBSol5g2Ulc7CLR7atgc9nzgcu4iXFDpPgnwy2FBjdBmuNlu6x8Q=="
privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCN3rLwTFH+bKixvMNh6NozixMy0ZRg7mCpdfDenGuLvgMSW0Fp6j5ff+0j8JfwVE7Eqo4ztNkNz1KeOqoj4tFeiltmpTsyoKFFOQdHNC3EK8cv8uto+5rVBSj/mZtLYA3exf1Dz+v41jdc6OTCtySSLL9aTfXB6vwpflGVv3PFNp3/w2h3oRvNUg5NIDahMrcEdckV/LbXOV4paULdpvJ02Ghjj36WCTWSHkXIYUsQdidSnGbqnPUtGpvQMM3r4L7xLscAs5e4xkDUhiIcOY8YbywsjD4JbXF5gLlmhPB8l73wJC/z84dTcLGLeJxTalZXBi/2eEGcsWvphqb54P/BAgMBAAECggEAPG9X7sG0VBvZqQ1udfEJstdV8FoTSU+C4e2aFFqx/a+OA23YadQdifUnAh5luz1O6Lx3I1Ow+w8MdNcsz2i6I/nwgcN1elWvHZvzm8OAk4bKrYRgADLefExccLXwz6U1g2b4QsD6FuC6aNvVR5VZAOQLB98aB+egT9S90HrkSGgb4y+KbXe58u0w0385Hsc+bvX/N6tzr8JDixfgIvP//WsUMpzQH3WIE2OPpz+b15IYqo0rTwh0DuiJS+ApGD9KYklvl2Ebtv2PMHi+hmPFyq2+CpokJVMxgJu3jYA22pRRKAmNf1uuW+bGri8Az6o4vWU7ZOZ5JOHtkyztcHrAAQKBgQDrI/BnPYpDp5PzWqwVSPtzUhi3qbEymIfo2vHwbiMVxx/S2dyrnMo4hKi/lLVugDwsuuIZG4YghgW5fxgVDhhVgh0Ln9UDbakrSRNq8eEpaupm38UVUZIicILDzL0QBYHWnnBR2oR3lbBhD1xssJtlgKPgo0+iigOtQiDZW6/FQQKBgQCadJQap4mZdRGIl5mEx+r/fZQoddyt093T44jFFgkpotqy8FXDXUEL+PDK0g6uxwHEMSgoipf3hZHrnHCdNO2ilVhlFXzuHna5wXCiTZdICYNxk8laWXzx32fGwCrVRVabhOGlpGrh+Ee+5c2XsA7sXbquKCK3NqtNKNB6XMYagQKBgDh2e86+p0nRnqRL/JBr4v1xFEBd/g/RMqmGkZwTRld/ZjPiXqvSzXg+2qqOUfbD0i9HfO1cf5ulsxA05ZqAtPUrdkAJVEQre/jJ5mDCzjd81eZ4C0IwQTAF5lCQBEIpoGDh0MTG/RIeHqlf3+i1i8sW1cMmVAQKshFTlMG803tBAoGAMPY5qMVpShshRsJ/6OaS6RC+8aCDJxtdW3jqd0eH+gnk+ApVtYuPPiNY+YJjIyZ0ueO3Tjq4978AxcaesEcB+aMMFWcdZkKD8liOwvSDu1NAtrVZg+mQQQBH3mo2acsELGKQQTkApMdWvv4MEUS/RlBkCCcy8g9DeD8y70cPiYECgYAZrL9dEsw3LkGrLKUDSzD7jaTZ153cCtCJHs+AEKaSEkM2bmdKsutiJnzfua+f+x8KhVoQg3sG6a8/9ujwRm8Vz36SLU4DKN59yyNSDh5W4nJwVI4NiVWoyxCYPw5tTO8ny6N+Wc7/UDa2g08AK9c7DjKMyD7+tlfIe2j7Atqodw=="
//prefix = "/ams/api"
prefix = "/ams/sandbox/api"
//ClientId = "5YBU7N2ZDN8S07987"
ClientId = "SANDBOX_5YBU7N2ZDN8S07987"
consult = "/v1/payments/consult"
pay = "/v1/payments/pay"
capture = "/v1/payments/capture"
inquiry = "/v1/payments/inquiryPayment"
cancel = "/v1/payments/cancel"
refund = "/v1/payments/refund"
)
type Amount struct {
Currency string `json:"currency"`
Value string `json:"value"`
}
type Env struct {
OsType string `json:"osType"`
TerminalType string `json:"terminalType"`
}
type ConsultPay struct {
ProductCode string `json:"productCode"`
PaymentAmount Amount `json:"paymentAmount"`
//UserRegion string `json:"userRegion"`
//MerchantRegion string `json:"merchantRegion"`
//SettlementStrategy struct {
// SettlementCurrency string `json:"settlementCurrency"`
//} `json:"settlementStrategy"`
AllowedPaymentMethodRegions []string `json:"allowedPaymentMethodRegions"`
Env Env `json:"env"`
PaymentFactor struct {
PresentmentMode string `json:"presentmentMode"`
} `json:"paymentFactor"`
}
type Logo struct {
LogoName string `json:"logoName"`
LogoUrl string `json:"logoUrl"`
}
type ConsultResult struct {
Result Result `json:"result"`
PaymentOptions []struct {
PaymentMethodType string `json:"paymentMethodType"`
PaymentMethodCategory string `json:"paymentMethodCategory"`
PaymentMethodRegion []string `json:"paymentMethodRegion"`
Enabled bool `json:"enabled"`
DisableReason string `json:"disableReason"`
Logo Logo `json:"logo"`
} `json:"paymentOptions"`
}
type PaymentMethod struct {
PaymentMethodType string `json:"paymentMethodType"`
PaymentMethodId string `json:"paymentMethodId"`
}
type CreatePay struct {
Env Env `json:"env"`
Order struct {
Merchant struct {
ReferenceMerchantID string `json:"referenceMerchantId"`
} `json:"merchant"`
OrderAmount Amount `json:"orderAmount"`
OrderDescription string `json:"orderDescription"`
ReferenceOrderID string `json:"referenceOrderId"`
} `json:"order"`
PaymentAmount Amount `json:"paymentAmount"`
PaymentMethod PaymentMethod `json:"paymentMethod"`
PaymentNotifyURL string `json:"paymentNotifyUrl"`
PaymentRedirectURL string `json:"paymentRedirectUrl"`
PaymentRequestID string `json:"paymentRequestId"` //商家分配的用于标识付款请求的唯一 ID。
ProductCode string `json:"productCode"` // 固定值
//SettlementStrategy struct {
//SettlementCurrency string `json:"settlementCurrency"`
//} `json:"settlementStrategy"`
}
type InStoreOrder struct {
Merchant struct {
ReferenceMerchantID string `json:"referenceMerchantId"`
MerchantMCC string `json:"merchantMCC"`
MerchantName string `json:"merchantName"`
Store struct {
ReferenceStoreId string `json:"referenceStoreId"`
StoreName string `json:"storeName"`
StoreMCC string `json:"storeMCC"`
} `json:"store"`
} `json:"merchant"`
OrderAmount Amount `json:"orderAmount"`
OrderDescription string `json:"orderDescription"`
ReferenceOrderID string `json:"referenceOrderId"`
Env Env `json:"env"`
PaymentMethod struct {
PaymentMethodType string `json:"paymentMethodType"`
PaymentMethodId string `json:"paymentMethodId"`
} `json:"paymentMethod"`
}
type InStorePay struct {
ProductCode string `json:"productCode"`
PaymentRequestID string `json:"paymentRequestId"`
Order InStoreOrder `json:"order"`
PaymentAmount Amount `json:"paymentAmount"`
PaymentMethod PaymentMethod `json:"paymentMethod"`
PaymentNotifyURL string `json:"paymentNotifyUrl"`
}
type Result struct {
ResultCode string `json:"resultCode"`
ResultMessage string `json:"resultMessage"`
ResultStatus string `json:"resultStatus"`
}
type RedirectActionForm struct {
Method string `json:"method"`
Parameters string `json:"parameters"`
RedirectUrl string `json:"redirectUrl"`
}
type OrderDetail struct {
Result Result `json:"result"`
PaymentRequestID string `json:"paymentRequestId"`
PaymentID string `json:"paymentId"`
PaymentAmount Amount `json:"paymentAmount"`
PaymentTime time.Time `json:"paymentTime"`
PaymentCreateTime string `json:"paymentCreateTime"`
AppIdentifier string `json:"appIdentifier"`
NormalURL string `json:"normalUrl"`
OrderCodeForm struct {
CodeDetails []struct {
CodeValue string `json:"codeValue"`
DisplayType string `json:"displayType"`
} `json:"codeDetails"`
ExpireTime string `json:"expireTime"`
} `json:"orderCodeForm"`
SchemeURL string `json:"schemeUrl"`
PaymentStatus string `json:"paymentStatus"`
RedirectActionForm RedirectActionForm `json:"redirectActionForm"`
Transactions any `json:"transactions"`
}
type Quote struct {
QuoteId string `json:"quoteId"`
QuoteCurrencyPair string `json:"quoteCurrencyPair"`
QuotePrice float64 `json:"quotePrice"`
QuoteStartTime time.Time `json:"quoteStartTime"`
QuoteExpiryTime time.Time `json:"quoteExpiryTime"`
Guaranteed bool `json:"guaranteed"`
}
type InStoreResult struct {
Result Result `json:"result"`
PaymentRequestID string `json:"paymentRequestId"`
PaymentID string `json:"paymentId"`
PaymentAmount Amount `json:"paymentAmount"`
PaymentTime time.Time `json:"paymentTime"`
PaymentCreateTime string `json:"paymentCreateTime"`
PspCustomerInfo struct {
PspName string `json:"pspName"`
PspCustomerId string `json:"pspCustomerId"`
DisplayCustomerId string `json:"displayCustomerId"`
} `json:"pspCustomerInfo"`
ChallengeActionForm struct {
ChallengeType string `json:"challengeType"`
TriggerSource string `json:"triggerSource"`
ExtendInfo string `json:"extendInfo"`
} `json:"challengeActionForm"`
RedirectActionForm RedirectActionForm `json:"redirectActionForm"`
GrossSettlementAmount Amount `json:"grossSettlementAmount"`
SettlementQuote Quote `json:"settlementQuote"`
}
type CapturePay struct {
PaymentID string `json:"paymentId"`
CaptureRequestID string `json:"captureRequestId"`
CaptureAmount Amount `json:"captureAmount"`
}
type CaptureDetail struct {
AcquirerReferenceNo string `json:"acquirerReferenceNo"`
Result Result `json:"result"`
CaptureTime string `json:"captureTime"`
PaymentID string `json:"paymentId"`
CaptureRequestID string `json:"captureRequestId"`
CaptureID string `json:"captureId"`
CaptureAmount Amount `json:"captureAmount"`
}
type NotifyPaymentParams struct {
NotifyType string `json:"notifyType"`
}
type CancelDetail struct {
Result Result `json:"result"`
PaymentRequestID string `json:"paymentRequestId"`
PaymentID string `json:"paymentId"`
CancelTime time.Time `json:"cancelTime"`
}
type RefundRequest struct {
RefundRequestId string `json:"refundRequestId"`
PaymentId string `json:"paymentId"`
ReferenceRefundId string `json:"referenceRefundId"`
RefundAmount Amount `json:"refundAmount"`
RefundReason string `json:"refundReason"`
RefundNotifyUrl string `json:"refundNotifyUrl"`
}
type RefundResult struct {
Result Result `json:"result"`
RefundRequestId string `json:"refundRequestId"`
RefundId string `json:"refundId"`
PaymentId string `json:"paymentId"`
AcquirerReferenceNo string `json:"acquirerReferenceNo"`
RefundAmount Amount `json:"refundAmount"`
RefundTime time.Time `json:"refundTime"`
GrossSettlementAmount Amount `json:"grossSettlementAmount"`
SettlementQuote Quote `json:"settlementQuote"`
}
func sign(requestURI, clientId, requestTime, requestBody string) string {
content := fmt.Sprintf("POST %s\n%s.%s.%s", requestURI, clientId, requestTime, requestBody)
block, _ := pem.Decode([]byte(util.FormatPrivateKey(privateKey)))
if block == nil {
panic("failed to parse PEM block containing the key")
}
priKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
panic(err)
}
hashed := sha256.Sum256([]byte(content))
signature, err := rsa.SignPKCS1v15(rand.Reader, priKey.(*rsa.PrivateKey), crypto.SHA256, hashed[:])
if err != nil {
panic(err)
}
encodedSignature := base64.StdEncoding.EncodeToString(signature)
urlEncodedSignature := url.QueryEscape(encodedSignature)
return urlEncodedSignature
}