我想在stripe中使用客户保存的支付方式进行支付,但我遇到了两个问题。
1). 我无法解码我的服务器端调用发送给应用程序的JSON响应,并得到了以下信息 Payment Method Id
. 我得到了完整的JSON响应,但是当我试图打印出 ID
它返回nil。
2). 如果用户保存了多种支付方式,当解码JSON响应以获得 Payment Method Id
?
预期的结果是让用户能够使用他们之前使用 "支付宝 "保存的支付方式。STPPaymentOptionsViewController
来进行支付,但上述两个问题依然存在。
服务器端。
exports.listUserSavedCards = functions.https.onRequest(async (req, res) => {
var customerId = req.body.customer_id
const paymentMethods = await stripe.paymentMethods.list({
customer: customerId,
type: 'card',
}).then(function(paymentMethods) {
// asynchronously called
return res.send(paymentMethods);
});
})
App Side: JSON Response:
func listUserSavedCards(customerId: String) {
let URLString = "https://us-central1-example.cloudfunctions.net/" + "listUserSavedCards" as String
var requestData : [String : String]? = [String : String]()
requestData?.updateValue(customerId, forKey: "customer_id");
submitDataToURL(URLString, withMethod: "POST", requestData: requestData!) { (jsonResponse, err) in
if err != nil {
print(err)
return
}
else {
let response = jsonResponse["id"]
}
}
}
JSON响应:
["url": /v1/payment_methods, "object": list, "has_more": 0, "data": <__NSSingleObjectArrayI
0x600002c46800>(
{
"billing_details" = {
address = {
city = "<null>";
country = "<null>";
line1 = "<null>";
line2 = "<null>";
"postal_code" = 4553;
state = "<null>";
};
email = "<null>";
name = "<null>";
phone = "<null>";
};
card = {
brand = mastercard;
checks = {
"address_line1_check" = "<null>";
"address_postal_code_check" = pass;
"cvc_check" = pass;
};
country = US;
"exp_month" = 2;
"exp_year" = 2021;
fingerprint = OqzEjapFroTZ3Lqn;
funding = credit;
"generated_from" = "<null>";
last4 = 4444;
"three_d_secure_usage" = {
supported = 1;
};
wallet = "<null>";
};
created = 1588901399;
customer = "cus_HDdTb2Me8W6MUM";
id = "pm_1GgL2JB7pjuLNBFRl48k0nyg";
livemode = 0;
metadata = {
};
object = "payment_method";
type = card;
}
)
]
Submit Data To Url:
do {
guard let url = URL(string: urlString) else {return};
let defaultSession = URLSession(configuration: .default)
var urlRequest = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 540)
urlRequest.httpMethod = method;
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") // the request is JSON
urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept") // the expected response is also JSON
let httpBodyData : Data?
try httpBodyData = JSONSerialization.data(withJSONObject: data, options: [.fragmentsAllowed]);
urlRequest.httpBody = httpBodyData;
let dataTask = defaultSession.dataTask(with: urlRequest, completionHandler: { (responseData, urlResponse, error) in
if error == nil {
do {
let response = try JSONSerialization.jsonObject(with: responseData!, options: [.fragmentsAllowed]) as! [String : Any];
completion(response, nil);
}
catch {
print("Exception")
let response : [String : Any] = [String : Any]()
completion(response, error);
}
}
else {
let response : [String : Any] = [String : Any]()
completion(response, error);
}
});
dataTask.resume();
}
catch {
print("Excetion in submitDataToURL")
}
}
paymentMethods.list
返回一个带有 data
属性,其中包含一个 PaymentMethods 数组。在你的代码中,你会用类似这样的方式来访问这个属性。
jsonResponse["data"][0]["id]
假设你正确地将JSON对象序列化在你的 submitDataToURL
函数。
我获取了 Id
使用下面的代码。
let response = jsonResponse
let results = response["data"] as? [[String: Any]]
let firstDict = results?.first
guard let id = firstDict?["id"] as? String else { return }