golang 实现苹果内购服务端验证

配置: config.go

package pay

import "time"

const (
	SandboxUrl        = "https://sandbox.itunes.apple.com/verifyReceipt" // (沙盒)链接
	ProductionUrl     = "https://buy.itunes.apple.com/verifyReceipt"     //  (正式)链接
	RequestUrlTimeout = 15 * time.Second                                 // 请求接口超时时间
)

var ResponseStatusMsg = map[int64]string{
	21000: "App Store 的请求不是使用 HTTP POST 请求方法发出的。", //·21000 对 App Store 的请求不是使用 HTTP POST 请求方法发出的。
	21001: "App Store 不再发送此状态代码。",                 //·21001 App Store 不再发送此状态代码。
	21002: "属性中的数据receipt-data格式不正确或服务遇到临时问题。",    //·21002 属性中的数据receipt-data格式不正确或服务遇到临时问题。再试一次。
	21003: "无法验证收据。",                              //·21003 无法验证收据。
	21004: "您提供的共享密钥与您帐户的文件共享密钥不匹配。",              //·21004 您提供的共享密钥与您帐户的文件共享密钥不匹配。
	21005: "收据服务器暂时无法提供收据。",                       //·21005 收据服务器暂时无法提供收据。再试一次
	21006: "此收据有效,但订阅已过期。",                        //·21006 此收据有效,但订阅已过期。当此状态代码返回到您的服务器时,收据数据也会被解码并作为响应的一部分返回。仅针对自动续订订阅的 iOS 6 样式交易收据返回。
	21007: "这条回执是来自测试环境,但它是发送到生产环境进行验证的。",         //·21007 这条回执是来自测试环境,但它是发送到生产环境进行验证的。
	21008: "这条回执来自生产环境,但它被发送到测试环境进行验证。",           //·21008 这条回执来自生产环境,但它被发送到测试环境进行验证。
	21009: "内部数据访问错误。",                            //·21009 内部数据访问错误。稍后再试。
	21010: "用户帐户找不到或已被删除。",                        //·21010 用户帐户找不到或已被删除。
}

逻辑处理部分

package pay

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
)

// 官方文档 https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
type Pay struct {
	Params   ParamsPay   `json:"params"`   //请求参数
	Response ResponsePay `json:"response"` // 返回参数
	Error    error       `json:"error"`    //错误信息
}

func NewPay() *Pay {
	return &Pay{
		Params:   ParamsPay{},
		Response: ResponsePay{},
		Error:    nil,
	}
}

// 请求参数
type ParamsPay struct {
	AppleClientId string `json:"appleClientId"` // 收据所属应用的捆绑包标识符(app应用的bundle_id)
	Password      string `json:"password"`      // 您的应用程序的共享密钥,它是一个十六进制字符串
	Url           string `json:"url"`           // 请求链接
	//TransactionId      string `json:"transactionId"`      // 交易的唯一标识符
	TransactionReceipt string `json:"transactionReceipt"` //Base64 编码的收据数据
}

// 内购支付返回的结构体 https://developer.apple.com/documentation/appstorereceipts/responsebody
type ResponsePay struct {
	Status      *int64 `json:"status"`      //具体注释看 config.ResponseStatusMsg 0:正确,其他失败
	Environment string `json:"environment"` //(生成收据的环境) 值:Sandbox(沙盒), Production(正式环境)
	Receipt     struct {
		ReceiptType                string `json:"receipt_type"`                // 生成的收据类型。该值对应于进行应用程序或 VPP 购买的环境。可能的值:Production, ProductionVPP, ProductionSandbox, ProductionVPPSandbox
		AdamId                     int64  `json:"adam_id"`                     //见。app_item_id
		AppItemId                  int64  `json:"app_item_id"`                 // 由 App Store Connect 生成并由 App Store 用于唯一标识所购买的应用程序。仅在生产中为应用分配此标识符。将此值视为 64 位长整数。
		ApplicationVersion         string `json:"application_version"`         // 应用程序的版本号。应用程序的版本号对应于. 在生产中,此值是设备上基于. 在沙盒中,该值始终为。CFBundleVersionCFBundleShortVersionStringInfo.plistreceipt_creation_date_m
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要安装gRPC和protobuf。可以使用以下命令: ``` go get -u google.golang.org/grpc go get -u github.com/golang/protobuf/proto go get -u github.com/golang/protobuf/protoc-gen-go ``` 接下来,我们需要定义protobuf文件,其中包含服务的RPC方法和消息格式,例如: ``` syntax = "proto3"; package myservice; message Request { string message = 1; } message Response { string message = 1; } service MyService { rpc SayHello(Request) returns (Response) {} } ``` 然后,使用以下命令将protobuf文件编译为Go代码: ``` protoc --go_out=plugins=grpc:. myservice.proto ``` 这将生成myservice.pb.go文件。 接下来,我们需要实现gRPC服务端和客户端。以下是一个简单的示例: 服务端: ``` package main import ( "log" "net" "google.golang.org/grpc" pb "path/to/myservice" ) type myServiceServer struct{} func (s *myServiceServer) SayHello(ctx context.Context, req *pb.Request) (*pb.Response, error) { log.Printf("Received message: %v", req.Message) return &pb.Response{Message: "Hello " + req.Message}, nil } func main() { lis, err := net.Listen("tcp", ":50051") if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterMyServiceServer(s, &myServiceServer{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } } ``` 客户端: ``` package main import ( "log" "golang.org/x/net/context" "google.golang.org/grpc" pb "path/to/myservice" ) func main() { conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() c := pb.NewMyServiceClient(conn) res, err := c.SayHello(context.Background(), &pb.Request{Message: "World"}) if err != nil { log.Fatalf("failed to call SayHello: %v", err) } log.Printf("Response message: %v", res.Message) } ``` 运行服务端和客户端,即可进行gRPC通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值