如何解析 paymentMethod 对象?
How to parse paymentMethod Object?
我正在尝试列出我用户的所有付款方式。我主要是想获取品牌,到期日期和信用卡号的后4位数字。
我尝试了多种方法来解析从我的服务器发回的 JSON 支付方式对象,但我还没有成功。这是我在最近一次尝试中所做的。
在我的服务器中,我得到了所有用户付款方式的列表,并使用此功能将原始数据发送回我的客户端:
exports.listPaymentMethods = functions.https.onCall(async (data, context) => {
const customerId = data.customer_id;
const paymentMethods = await stripe.paymentMethods.list({
customer: customerId,
type: "card",
});
const pymtMethodData = paymentMethods.data;
return {
data: pymtMethodData,
};
});
这是我从客户端调用函数的方式(它成功打印了原始数据):
func listPaymentMethods(customerID: String) {
FirebaseReferenceManager.functions.httpsCallable("listPaymentMethods").call(["customer_id": customerID]) { (response, error) in
if let error = error {
print("failed to list customer's payment methods: \(error.localizedDescription)")
}
if let response = response?.data as? [String: Any] {
let data = response["data"]
print(data!)
self.parseJSON(data: data as! Data)
}
}
}
这是我用来存储支付方式数据的结构:
struct PaymentMethod: Decodable {
let brand: String
let expMonth: Int
let expYear: Int
let last4: Int
}
我尝试使用这个函数来解析数据,但是没有成功:
func parseJSON(data: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(PaymentMethod.self, from: data)
print(decodedData.brand)
} catch {
print(error)
}
}
这是我从print(data!)
得到的原始数据
(
{
"billing_details" = {
address = {
city = "<null>";
country = US;
line1 = "<null>";
line2 = "<null>";
"postal_code" = 123456;
state = "<null>";
};
email = "<null>";
name = "<null>";
phone = "<null>";
};
card = {
brand = visa;
checks = {
"address_line1_check" = "<null>";
"address_postal_code_check" = pass;
"cvc_check" = pass;
};
country = US;
"exp_month" = 12;
"exp_year" = 2045;
fingerprint = KKSbyUhUcKKSyto0;
funding = credit;
"generated_from" = "<null>";
last4 = 4242;
networks = {
available = (
visa
);
preferred = "<null>";
};
"three_d_secure_usage" = {
supported = 1;
};
wallet = "<null>";
};
created = 1621941861;
customer = "cus_JWaE2JEtbcI0JM";
id = "pm_1IuyMzLVD5W50FFK2heBUTai";
livemode = 0;
metadata = {
};
object = "payment_method";
type = card;
}
)
我基本上是在尝试解析 JSON 数据,以便我可以拥有一个 PaymentMethod 数组(我在上面添加的结构),以便独立地引用来自该 PaymentMethod 的每个单独数据。
任何能引导我走向正确方向的东西都将不胜感激! :)
response.data
已经被解析成Swift个对象,是一个[[String: Any]]
。不再是Data
,不需要JSONDecoder
。
在 PaymentMethod
添加自定义初始化:
init?(paymentDict: [String: Any]) {
guard let card = paymentDict["card"] as? [String: Any] else {
print("There is no \"card\" key or it's not a [String: Any] in: \(paymentDict)")
return nil
}
guard let brand = card["brand"] as? String else {
print("There is no \"brand\" key or it's not a String in: \(card)")
return nil
}
guard let expMonth = card["expMonth"] as? Int else {
print("There is no \"expMonth\" key or it's not a Int in: \(card)")
return nil
}
guard let expYear = card["expYear"] as? Int else {
print("There is no \"expYear\" key or it's not a Int in: \(card)")
return nil
}
guard let last4 = card["last4"] as? Int else {
print("There is no \"last4\" key or it's not a Int in: \(card)")
return nil
}
self.brand = brand
self.expMonth = expMonth
self.expYear = expYear
self.last4 = last4
}
因为 response.data
是 Dictionary
的 Array
而不是 Dictionary
,如果您只对解析第一个感兴趣:
if let response = response?.data as? [String: Any] {
if let data = response["data"] {
if let firstPaymentDictionary = data.first {
if let payment = PaymentMethod(paymentDict: firstPaymentDictionary) {
print("Payment found: \(payment)")
} else {
print("Invalid payment)
}
} else {
print("No payment found in `\(data)`")
}
} else {
print("No data in \(response)")
}
}
旁注:
我在 if let
中添加了所有 else
并在 guard let
的 else
中添加了显式打印,让您知道什么可能是错误的以及它们的含义。因为 if let
/guard let
应该优于 !
.
我正在尝试列出我用户的所有付款方式。我主要是想获取品牌,到期日期和信用卡号的后4位数字。
我尝试了多种方法来解析从我的服务器发回的 JSON 支付方式对象,但我还没有成功。这是我在最近一次尝试中所做的。
在我的服务器中,我得到了所有用户付款方式的列表,并使用此功能将原始数据发送回我的客户端:
exports.listPaymentMethods = functions.https.onCall(async (data, context) => {
const customerId = data.customer_id;
const paymentMethods = await stripe.paymentMethods.list({
customer: customerId,
type: "card",
});
const pymtMethodData = paymentMethods.data;
return {
data: pymtMethodData,
};
});
这是我从客户端调用函数的方式(它成功打印了原始数据):
func listPaymentMethods(customerID: String) {
FirebaseReferenceManager.functions.httpsCallable("listPaymentMethods").call(["customer_id": customerID]) { (response, error) in
if let error = error {
print("failed to list customer's payment methods: \(error.localizedDescription)")
}
if let response = response?.data as? [String: Any] {
let data = response["data"]
print(data!)
self.parseJSON(data: data as! Data)
}
}
}
这是我用来存储支付方式数据的结构:
struct PaymentMethod: Decodable {
let brand: String
let expMonth: Int
let expYear: Int
let last4: Int
}
我尝试使用这个函数来解析数据,但是没有成功:
func parseJSON(data: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(PaymentMethod.self, from: data)
print(decodedData.brand)
} catch {
print(error)
}
}
这是我从print(data!)
(
{
"billing_details" = {
address = {
city = "<null>";
country = US;
line1 = "<null>";
line2 = "<null>";
"postal_code" = 123456;
state = "<null>";
};
email = "<null>";
name = "<null>";
phone = "<null>";
};
card = {
brand = visa;
checks = {
"address_line1_check" = "<null>";
"address_postal_code_check" = pass;
"cvc_check" = pass;
};
country = US;
"exp_month" = 12;
"exp_year" = 2045;
fingerprint = KKSbyUhUcKKSyto0;
funding = credit;
"generated_from" = "<null>";
last4 = 4242;
networks = {
available = (
visa
);
preferred = "<null>";
};
"three_d_secure_usage" = {
supported = 1;
};
wallet = "<null>";
};
created = 1621941861;
customer = "cus_JWaE2JEtbcI0JM";
id = "pm_1IuyMzLVD5W50FFK2heBUTai";
livemode = 0;
metadata = {
};
object = "payment_method";
type = card;
}
)
我基本上是在尝试解析 JSON 数据,以便我可以拥有一个 PaymentMethod 数组(我在上面添加的结构),以便独立地引用来自该 PaymentMethod 的每个单独数据。
任何能引导我走向正确方向的东西都将不胜感激! :)
response.data
已经被解析成Swift个对象,是一个[[String: Any]]
。不再是Data
,不需要JSONDecoder
。
在 PaymentMethod
添加自定义初始化:
init?(paymentDict: [String: Any]) {
guard let card = paymentDict["card"] as? [String: Any] else {
print("There is no \"card\" key or it's not a [String: Any] in: \(paymentDict)")
return nil
}
guard let brand = card["brand"] as? String else {
print("There is no \"brand\" key or it's not a String in: \(card)")
return nil
}
guard let expMonth = card["expMonth"] as? Int else {
print("There is no \"expMonth\" key or it's not a Int in: \(card)")
return nil
}
guard let expYear = card["expYear"] as? Int else {
print("There is no \"expYear\" key or it's not a Int in: \(card)")
return nil
}
guard let last4 = card["last4"] as? Int else {
print("There is no \"last4\" key or it's not a Int in: \(card)")
return nil
}
self.brand = brand
self.expMonth = expMonth
self.expYear = expYear
self.last4 = last4
}
因为 response.data
是 Dictionary
的 Array
而不是 Dictionary
,如果您只对解析第一个感兴趣:
if let response = response?.data as? [String: Any] {
if let data = response["data"] {
if let firstPaymentDictionary = data.first {
if let payment = PaymentMethod(paymentDict: firstPaymentDictionary) {
print("Payment found: \(payment)")
} else {
print("Invalid payment)
}
} else {
print("No payment found in `\(data)`")
}
} else {
print("No data in \(response)")
}
}
旁注:
我在 if let
中添加了所有 else
并在 guard let
的 else
中添加了显式打印,让您知道什么可能是错误的以及它们的含义。因为 if let
/guard let
应该优于 !
.