go苹果支付后端回调验证
时间: 2025-05-14 19:24:13 浏览: 16
### Go语言实现苹果支付(IAP)后端回调验证
为了确保iOS应用内购买的安全性和可靠性,在完成一次交易之后,服务端需要对接收到的收据(receipt)进行验证。这通常涉及到向Apple的服务发送HTTP请求并解析返回的数据。
#### 验证流程概述
当接收到客户端传来的purchase token或者其他形式的凭证时,应该构建特定结构体来封装这些信息,并将其序列化成JSON字符串作为POST请求的一部分提交至官方提供的URL地址[^1]。对于沙盒环境测试期间以及生产环境中所使用的校验链接有所不同:
- 测试/开发阶段:`https://sandbox.itunes.apple.com/verifyReceipt`
- 正式发布版本:`https://buy.itunes.apple.com/verifyReceipt`
#### 实现细节
下面展示了一个简单的函数用于执行上述过程中的核心逻辑——即发起网络请求并与响应交互的部分。此段代码假设已经获取到了来自用户的原始票据(base64编码后的receipt data),并且准备好了必要的配置项如超时设置等。
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
// ReceiptData represents the structure of receipt information.
type ReceiptData struct {
Receipt string `json:"receipt-data"`
}
// ResponseBody defines what we expect back from Apple's servers after verification.
type ResponseBody struct {
Status int `json:"status"` // Status code indicating success or failure reasons
Latest_receipt_info []map[string]interface{} `json:"latest_receipt_info,omitempty"` // Details about latest successful purchase(s), if any
}
func verifyPurchase(receiptBase64Encoded string, isProduction bool) (*ResponseBody, error){
var url string
if !isProduction {
url = "https://sandbox.itunes.apple.com/verifyReceipt"
} else {
url = "https://buy.itunes.apple.com/verifyReceipt"
}
payload := &ReceiptData{Receipt: receiptBase64Encoded}
jsonPayload, err := json.Marshal(payload)
if err != nil{
return nil,err
}
resp, err := http.Post(url,"application/json",bytes.NewBuffer(jsonPayload))
if err!=nil || resp.StatusCode>=400{
defer resp.Body.Close()
bodyText,_:=ioutil.ReadAll(resp.Body)
fmt.Printf("Error occurred while verifying with apple:%s\n",string(bodyText))
return nil,fmt.Errorf("failed to post request")
}else{
defer resp.Body.Close()
result := new(ResponseBody)
err=json.Unmarshal(ioutil.ReadAll(resp.Body),result)
if err==nil && result.Status==0{
return result,nil
}else{
return nil,fmt.Errorf("invalid status returned by apple server %d",result.Status)
}
}
}
```
该方法接受两个参数:一个是base64编码过的收据文本;另一个指示当前运行模式(true代表线上环境)。它会尝试连接到相应的API endpoint并将结果反序列化为自定义类型的实例以便进一步处理。
#### 安全考量
值得注意的是,在实际部署之前还需要考虑更多方面以增强系统的安全性,比如但不限于:
- 对所有外部输入做严格的格式检查;
- 使用HTTPS协议保护传输层安全;
- 设置合理的重试机制应对临时性的网络波动;
- 记录详细的日志方便后续排查问题等等。
阅读全文
相关推荐

















