Skip to content

Commit

Permalink
添加文件上传
Browse files Browse the repository at this point in the history
  • Loading branch information
smartwalle committed Jun 28, 2023
1 parent 07542d1 commit 0108bdc
Show file tree
Hide file tree
Showing 14 changed files with 121 additions and 16 deletions.
26 changes: 14 additions & 12 deletions alipay.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package alipay

import (
"context"
"crypto"
"crypto/md5"
"crypto/rsa"
Expand All @@ -9,6 +10,7 @@ import (
"encoding/hex"
"encoding/json"
"errors"
"github.com/smartwalle/ngx"
"github.com/smartwalle/nsign"
"io"
"net/http"
Expand Down Expand Up @@ -43,7 +45,7 @@ type Client struct {
onReceivedData func(method string, data []byte)

// 内容加密
encryptNeed bool
needEncrypt bool
encryptIV []byte
encryptType string
encryptKey []byte
Expand Down Expand Up @@ -164,15 +166,15 @@ func (this *Client) IsProduction() bool {
// SetEncryptKey 接口内容加密密钥 https://opendocs.alipay.com/common/02mse3
func (this *Client) SetEncryptKey(key string) error {
if key == "" {
this.encryptNeed = false
this.needEncrypt = false
return nil
}

var data, err = base64.StdEncoding.DecodeString(key)
if err != nil {
return err
}
this.encryptNeed = true
this.needEncrypt = true
this.encryptIV = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
this.encryptType = "AES"
this.encryptKey = data
Expand Down Expand Up @@ -339,7 +341,7 @@ func (this *Client) URLValues(param Param) (value url.Values, err error) {
}

var content = string(jsonBytes)
if this.encryptNeed && param.APIName() != kCertDownloadAPI {
if this.needEncrypt && param.NeedEncrypt() {
jsonBytes, err = ncrypto.AESCBCEncrypt(jsonBytes, this.encryptKey, this.encryptIV, this.encryptPadding)
if err != nil {
return nil, err
Expand Down Expand Up @@ -367,23 +369,23 @@ func (this *Client) URLValues(param Param) (value url.Values, err error) {
}

func (this *Client) doRequest(method string, param Param, result interface{}) (err error) {
var body io.Reader
var req = ngx.NewRequest(method, this.host, ngx.WithClient(this.Client))
req.SetContentType(kContentType)
if param != nil {
var values url.Values
values, err = this.URLValues(param)
if err != nil {
return err
}
body = strings.NewReader(values.Encode())
}
req.SetParams(values)

req, err := http.NewRequest(method, this.host, body)
if err != nil {
return err
var files = param.FileParams()
for _, file := range files {
req.AddFile(file.Name, file.Filename, file.Filepath)
}
}
req.Header.Set("Content-Type", kContentType)

rsp, err := this.Client.Do(req)
rsp, err := req.Do(context.Background())
if err != nil {
return err
}
Expand Down
63 changes: 59 additions & 4 deletions alipay_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,43 @@ type Param interface {

// Params 返回公共请求参数
Params() map[string]string

// FileParams 返回文件参数
FileParams() map[string]*FileItem

// NeedEncrypt 返回该接口是否支持内容加密,有的接口不支持内容加密,比如文件上传接口:alipay.open.file.upload
NeedEncrypt() bool
}

type AuxParam struct {
}

func (this AuxParam) FileParams() map[string]*FileItem {
return nil
}

func (this AuxParam) NeedEncrypt() bool {
return true
}

type FileItem struct {
Name string
Filename string
Filepath string
}

type Payload struct {
method string
param map[string]string
biz map[string]interface{}
method string
Encrypt bool
param map[string]string
biz map[string]interface{}
files map[string]*FileItem
}

func NewPayload(method string) *Payload {
var nPayload = &Payload{}
nPayload.method = method
nPayload.Encrypt = true
nPayload.param = make(map[string]string)
nPayload.biz = make(map[string]interface{})
return nPayload
Expand All @@ -82,6 +108,14 @@ func (this *Payload) Params() map[string]string {
return this.param
}

func (this *Payload) FileParams() map[string]*FileItem {
return this.files
}

func (this *Payload) NeedEncrypt() bool {
return this.Encrypt
}

// AddParam 添加公共请求参数
//
// 例如:https://opendocs.alipay.com/apis/api_1/alipay.trade.query/#%E5%85%AC%E5%85%B1%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0
Expand All @@ -90,14 +124,30 @@ func (this *Payload) AddParam(key, value string) *Payload {
return this
}

// Set 添加请求参数(业务相关)
// Set 添加请求参数(业务相关),这里添加的参数会序列化成 JSON 字符串,然后通过 biz_content 参数传递
//
// 例如:https://opendocs.alipay.com/apis/api_1/alipay.trade.query/#%E8%AF%B7%E6%B1%82%E5%8F%82%E6%95%B0
func (this *Payload) Set(key string, value interface{}) *Payload {
this.biz[key] = value
return this
}

// AddFile 添加需要上传的文件
//
// name: 参数名称
// filename: 文件名称
// filepath: 本地文件完整路径
func (this *Payload) AddFile(name, filename, filepath string) {
if this.files == nil {
this.files = make(map[string]*FileItem)
}

if filename == "" {
filename = name
}
this.files[name] = &FileItem{Name: name, Filename: filename, Filepath: filepath}
}

func (this *Payload) MarshalJSON() ([]byte, error) {
return json.Marshal(this.biz)
}
Expand Down Expand Up @@ -127,6 +177,7 @@ const (

// CertDownload 应用支付宝公钥证书下载 https://opendocs.alipay.com/common/06ue2z
type CertDownload struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
AliPayCertSN string `json:"alipay_cert_sn"` // 支付宝公钥证书序列号
}
Expand All @@ -141,6 +192,10 @@ func (this CertDownload) Params() map[string]string {
return m
}

func (this CertDownload) NeedEncrypt() bool {
return false
}

type CertDownloadRsp struct {
Error
AliPayCertContent string `json:"alipay_cert_content"`
Expand Down
6 changes: 6 additions & 0 deletions authorize_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const (

// SystemOauthToken 换取授权访问令牌接口请求参数 https://docs.open.alipay.com/api_9/alipay.system.oauth.token
type SystemOauthToken struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
GrantType string `json:"-"` // 值为 authorization_code 时,代表用code换取;值为refresh_token时,代表用refresh_token换取
Code string `json:"-"`
Expand Down Expand Up @@ -49,6 +50,7 @@ type SystemOauthTokenRsp struct {

// UserInfoShare 支付宝会员授权信息查询接口请求参数 https://docs.open.alipay.com/api_2/alipay.user.info.share
type UserInfoShare struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
AuthToken string `json:"-"` // 是
}
Expand Down Expand Up @@ -82,6 +84,7 @@ type UserInfoShareRsp struct {

// OpenAuthTokenApp 换取应用授权令牌请求参数 https://docs.open.alipay.com/api_9/alipay.open.auth.token.app
type OpenAuthTokenApp struct {
AuxParam
GrantType string `json:"grant_type"` // 值为 authorization_code 时,代表用code换取;值为refresh_token时,代表用refresh_token换取
Code string `json:"code"`
RefreshToken string `json:"refresh_token"`
Expand Down Expand Up @@ -120,6 +123,7 @@ type OpenAuthToken struct {

// OpenAuthTokenAppQuery 查询某个应用授权AppAuthToken的授权信息 https://opendocs.alipay.com/isv/04hgcp?pathHash=7ea21afe
type OpenAuthTokenAppQuery struct {
AuxParam
AppAuthToken string `json:"app_auth_token"` // 必选 应用授权令牌
}

Expand All @@ -145,6 +149,7 @@ type OpenAuthTokenAppQueryRsp struct {

// AccountAuth 支付宝登录时, 帮客户端做参数签名, 返回授权请求信息字串接口请求参数 https://docs.open.alipay.com/218/105327/
type AccountAuth struct {
AuxParam
Pid string `json:"pid"`
TargetId string `json:"target_id"`
AuthType string `json:"auth_type"`
Expand All @@ -169,6 +174,7 @@ func (this AccountAuth) Params() map[string]string {

// OpenAuthAppAuthInviteCreate ISV向商户发起应用授权邀约 https://opendocs.alipay.com/isv/06evao?pathHash=f46ecafa
type OpenAuthAppAuthInviteCreate struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
AuthAppId string `json:"auth_app_id"` // 必选 指定授权的商户appid
RedirectURL string `json:"redirect_url"` // 可选 授权回调地址,用于返回应用授权码
Expand Down
3 changes: 3 additions & 0 deletions bill_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package alipay

// BillDownloadURLQuery 查询对账单下载地址接口请求参数 https://docs.open.alipay.com/api_15/alipay.data.dataservice.bill.downloadurl.query
type BillDownloadURLQuery struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
BillType string `json:"bill_type"` // 必选 账单类型,商户通过接口或商户经开放平台授权后其所属服务商通过接口可以获取以下账单类型:trade、signcustomer;trade指商户基于支付宝交易收单的业务账单;signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单。
BillDate string `json:"bill_date"` // 必选 账单时间:日账单格式为yyyy-MM-dd,最早可下载2016年1月1日开始的日账单;月账单格式为yyyy-MM,最早可下载2016年1月开始的月账单。
Expand All @@ -19,6 +20,7 @@ func (this BillDownloadURLQuery) Params() map[string]string {

// BillAccountLogQuery 查询账户账务明细接口请求参数 https://opendocs.alipay.com/apis/api_15/alipay.data.bill.accountlog.query
type BillAccountLogQuery struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
StartTime string `json:"start_time"` // 账务流水创建时间的起始范围 2019-01-01 00:00:00
EndTime string `json:"end_time"` // 账务流水创建时间的结束范围。与起始时间间隔不超过31天。查询结果为起始时间至结束时间的左闭右开区间 2019-01-02 00:00:00
Expand Down Expand Up @@ -78,6 +80,7 @@ type BillDownloadURLQueryRsp struct {

// BillBalanceQuery 支付宝商家账户当前余额查询 https://opendocs.alipay.com/apis/api_15/alipay.data.bill.balance.query
type BillBalanceQuery struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
}

Expand Down
5 changes: 5 additions & 0 deletions certify_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (

// UserCertifyOpenInitialize 身份认证初始化服务接口请求参数 https://docs.open.alipay.com/api_2/alipay.user.certify.open.initialize
type UserCertifyOpenInitialize struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
OuterOrderNo string `json:"outer_order_no"` // 必选 商户请求的唯一标识,商户要保证其唯一性,值为32位长度的字母数字组合。建议:前面几位字符是商户自定义的简称,中间可以使用一段时间,后段可以使用一个随机或递增序列
BizCode CertifyBizCode `json:"biz_code"` // 必选 认证场景码。入参支持的认证场景码和商户签约的认证场景相关,取值如下: FACE:多因子人脸认证 CERT_PHOTO:多因子证照认证 CERT_PHOTO_FACE :多因子证照和人脸认证 SMART_FACE:多因子快捷认证
Expand Down Expand Up @@ -48,6 +49,7 @@ type UserCertifyOpenInitializeRsp struct {

// UserCertifyOpenCertify 身份认证开始认证接口请求参数 https://docs.open.alipay.com/api_2/alipay.user.certify.open.certify
type UserCertifyOpenCertify struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
CertifyId string `json:"certify_id"` // 必选 本次申请操作的唯一标识,由开放认证初始化接口调用后生成,后续的操作都需要用到
}
Expand All @@ -69,6 +71,7 @@ type UserCertifyOpenCertifyRsp struct {

// UserCertifyOpenQuery 身份认证记录查询接口请求参数 https://docs.open.alipay.com/api_2/alipay.user.certify.open.query/
type UserCertifyOpenQuery struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
CertifyId string `json:"certify_id"` // 必选 本次申请操作的唯一标识,由开放认证初始化接口调用后生成,后续的操作都需要用到
}
Expand All @@ -93,6 +96,7 @@ type UserCertifyOpenQueryRsp struct {

// UserCertDocCertVerifyPreConsult 实名证件信息比对验证预咨询接口请求参数 https://opendocs.alipay.com/apis/api_2/alipay.user.certdoc.certverify.preconsult
type UserCertDocCertVerifyPreConsult struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
UserName string `json:"user_name"` // 真实姓名
CertType string `json:"cert_type"` // 证件类型。暂仅支持 IDENTITY_CARD (身份证)。 ID
Expand Down Expand Up @@ -120,6 +124,7 @@ type UserCertDocCertVerifyPreConsultRsp struct {

// UserCertDocCertVerifyConsult 实名证件信息比对验证咨询接口请求参数 https://opendocs.alipay.com/apis/api_2/alipay.user.certdoc.certverify.consult
type UserCertDocCertVerifyConsult struct {
AuxParam
AppAuthToken string `json:"-"` // 可选
VerifyId string `json:"verify_id"` // 信息校验验证ID。通过alipay.user.certdoc.certverify.preconsult(实名证件信息比对验证预咨询)接口获取
}
Expand Down
1 change: 1 addition & 0 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/smartwalle/ncrypto v1.0.2 // indirect
github.com/smartwalle/nsign v1.0.8
github.com/smartwalle/xid v1.0.6
github.com/smartwalle/ngx v1.0.6
)

replace github.com/smartwalle/alipay/v3 => ../
2 changes: 2 additions & 0 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/smartwalle/ncrypto v1.0.1 h1:CVe/h/srt6knLiF/9V5OnDDhguskWR801meHizq7
github.com/smartwalle/ncrypto v1.0.1/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
github.com/smartwalle/ncrypto v1.0.2 h1:pTAhCqtPCMhpOwFXX+EcMdR6PNzruBNoGQrN2S1GbGI=
github.com/smartwalle/ncrypto v1.0.2/go.mod h1:Dwlp6sfeNaPMnOxMNayMTacvC5JGEVln3CVdiVDgbBk=
github.com/smartwalle/ngx v1.0.6 h1:JPNqNOIj+2nxxFtrSkJO+vKJfeNUSEQueck/Wworjps=
github.com/smartwalle/ngx v1.0.6/go.mod h1:mx/nz2Pk5j+RBs7t6u6k22MPiBG/8CtOMpCnALIG8Y0=
github.com/smartwalle/nsign v0.0.1 h1:fpEwoThIjr1JRPqz5hEwbH5ADX/so6G/zcwvj0ywYyM=
github.com/smartwalle/nsign v0.0.1/go.mod h1:eY6I4CJlyNdVMP+t6z1H6Jpd4m5/V+8xi44ufSTxXgc=
github.com/smartwalle/nsign v1.0.8 h1:78KWtwKPrdt4Xsn+tNEBVxaTLIJBX9YRX0ZSrMUeuHo=
Expand Down
Loading

0 comments on commit 0108bdc

Please sign in to comment.