diff --git a/api/proto/vas/proto/pay.go b/api/proto/vas/proto/pay.go index dfa22391..c31c4c2f 100644 --- a/api/proto/vas/proto/pay.go +++ b/api/proto/vas/proto/pay.go @@ -33,12 +33,14 @@ const ( PayTypeWxpayJsapi = "wxpay_jsapi" // 微信 jsapi PayTypeWxpayH5 = "wxpay_h5" // 微信支付 h5 PayTypeCoin = "coin" // 金币支付 + PayTypeApplepay = "applepay" // ios iap 支付 ) const ( - CallBackPayTypeAlipay = "alipay" - CallBackPayTypeWxpay = "wxpay" - CallBackPayTypeCoin = "coin" + CallBackPayTypeAlipay = "alipay" + CallBackPayTypeWxpay = "wxpay" + CallBackPayTypeCoin = "coin" + CallBackPayTypeApplepay = "applepay" ) const ( diff --git a/app/mix/controller/applepay_callback.go b/app/mix/controller/applepay_callback.go index acbab2db..818daf40 100644 --- a/app/mix/controller/applepay_callback.go +++ b/app/mix/controller/applepay_callback.go @@ -5,19 +5,29 @@ import ( "github.com/gin-gonic/gin" "io/ioutil" "net/http" - "service/bizcommon/util" + "service/app/mix/service" "service/library/logger" + "service/library/payclients/applepaycli" ) func ApplepayCallback(ctx *gin.Context) { - var bodyParam map[string]interface{} + var notify = applepaycli.ApplepayRevenueNotify{} buf, err := ioutil.ReadAll(ctx.Request.Body) logger.Info("ApplepayCallback body: %v", string(buf)) - err = json.Unmarshal(buf, &bodyParam) + + err = json.Unmarshal(buf, ¬ify) if err != nil { logger.Error("arg parse fail: %v", err) ReplyJsonError(ctx, http.StatusBadRequest, "参数解析失败") return } - logger.Info("ApplepayCallback param: %v", util.ToJson(bodyParam)) + + err = service.DefaultService.ApplepayCallback(ctx, notify) + if err != nil { + logger.Error("ApplepayCallback fail: %v", err) + ReplyJsonError(ctx, -1, err.Error()) + return + } + + ctx.String(200, "success") } diff --git a/app/mix/service/vasservice.go b/app/mix/service/vasservice.go index 0fe275c9..0ea43787 100644 --- a/app/mix/service/vasservice.go +++ b/app/mix/service/vasservice.go @@ -4,16 +4,20 @@ import ( "encoding/base64" "fmt" goproto "google.golang.org/protobuf/proto" + "service/api/base" "service/api/errcode" "service/api/errs" accountproto "service/api/proto/account/proto" vasproto "service/api/proto/vas/proto" vericodeproto "service/api/proto/vericode/proto" zoneproto "service/api/proto/zone/proto" + "service/bizcommon/common" "service/bizcommon/util" "service/dbstruct" "service/library/logger" "service/library/mycrypto" + "service/library/payclients/applepaycli" + "strconv" "github.com/gin-gonic/gin" ) @@ -1079,3 +1083,49 @@ func (s *Service) OpManualUnlockWechat(ctx *gin.Context, req *zoneproto.OpManual } return } + +func (s *Service) ApplepayCallback(ctx *gin.Context, notify applepaycli.ApplepayRevenueNotify) error { + var ( + event = notify.Event + mid, _ = strconv.ParseInt(event.AppUserID, 10, 64) + ) + + // 验证用户 + acnt, _ := _DefaultAccount.GetAccountMapByMids(ctx, []int64{mid}) + if _, ok := acnt[mid]; !ok { + err := fmt.Errorf("invalid user") + logger.Error("ApplepayCallback fail, invalid user, mid: %v, notify: %v", mid, notify) + return err + } + + // 先创建订单 + createOrderParam := &vasproto.CreateOrderReq{ + BaseRequest: base.BaseRequest{ + Mid: mid, + DevType: common.DeviceTypeIos, + }, + ProductId: event.ProductID, + PayType: vasproto.PayTypeCoin, + Oid3: event.AppID, + } + data, err := _DefaultVas.CreateOrder(ctx, createOrderParam) + if err != nil { + logger.Error("CreateOrder fail, param: %v, err: %v", createOrderParam, err) + return err + } + orderId := data.OrderId + + // 手动回调 + payCallbackParam := &vasproto.PayCallbackParamIn{ + OrderId: orderId, + OutOrderId: event.TransactionID, + CallbackPayType: vasproto.CallBackPayTypeApplepay, + } + err = _DefaultVas.PayCallback(ctx, payCallbackParam) + if err != nil { + logger.Error("PayCallback fail, param: %v, err: %v", payCallbackParam, err) + return err + } + + return nil +} diff --git a/library/payclients/applepaycli/proto.go b/library/payclients/applepaycli/proto.go new file mode 100644 index 00000000..096ad312 --- /dev/null +++ b/library/payclients/applepaycli/proto.go @@ -0,0 +1,42 @@ +package applepaycli + +type Event struct { + EventTimestampMs int64 `json:"event_timestamp_ms"` + ProductID string `json:"product_id"` + PeriodType string `json:"period_type"` + PurchasedAtMs int64 `json:"purchased_at_ms"` + ExpirationAtMs int64 `json:"expiration_at_ms"` + Environment string `json:"environment"` + EntitlementID string `json:"entitlement_id"` + EntitlementIDs []string `json:"entitlement_ids"` + PresentedOfferingID string `json:"presented_offering_id"` + TransactionID string `json:"transaction_id"` + OriginalTransactionID string `json:"original_transaction_id"` + IsFamilyShare bool `json:"is_family_share"` + CountryCode string `json:"country_code"` + AppUserID string `json:"app_user_id"` + Aliases []string `json:"aliases"` + OriginalAppUserID string `json:"original_app_user_id"` + Currency string `json:"currency"` + Price float64 `json:"price"` + PriceInPurchasedCurrency float64 `json:"price_in_purchased_currency"` + SubscriberAttributes struct { + AttConsentStatus struct { + Value string `json:"value"` + UpdatedAtMs int64 `json:"updated_at_ms"` + } `json:"$attConsentStatus"` + } `json:"subscriber_attributes"` + Store string `json:"store"` + TakehomePercentage float64 `json:"takehome_percentage"` + OfferCode string `json:"offer_code"` + TaxPercentage float64 `json:"tax_percentage"` + CommissionPercentage float64 `json:"commission_percentage"` + Type string `json:"type"` + ID string `json:"id"` + AppID string `json:"app_id"` +} + +type ApplepayRevenueNotify struct { + Event Event `json:"event"` + APIVersion string `json:"api_version"` +}