创建和更新卡片
了解什么是 Marqeta 卡,以及如何创建和更新它。
一张**卡片**是用户拥有的支付卡,可以是实体卡或虚拟卡。卡片的行为和属性由与其关联的卡片产品对象定义。我们也可以在卡片对象中定义卡片的属性,此时卡片对象中的定义将优先于卡片产品对象中的定义。
在本课程中,我们将学习如何创建和更新 Marqeta 支付卡。
创建卡片
我们可以通过向 {BASE_URL}/cards 端点发送 POST 请求来创建一张 Marqeta 支付卡。可以在请求体中提供卡片的基本信息,包括邮寄信息。同时,还需要指定卡片所有者的 user_token 以及控制该卡片的卡片产品 card_product_token。因此,在创建新的 Marqeta 卡片之前,我们需要先创建一个用户和一个卡片产品。
请求参数
| 参数 | 类型 | 分类 | 描述 |
|---|---|---|---|
| show_cvv_number | 布尔值 | 可选 | true 表示在响应中显示 CVV2 数字,否则为 false。注意:这是查询参数。 |
| show_pan | 布尔值 | 可选 | true 表示在响应中显示卡片的 PAN(主账户号码),否则为 false。注意:这是查询参数。 |
| card_product_token | 字符串 | 可选 | 卡片产品的令牌 |
| expedite | 布尔值 | 可选 | 为请求履约提供商加快卡片处理时设为 true,否则为 false。默认值:false |
| metadata | 对象 | 可选 | 将客户提供的元数据添加到卡片中。允许值:最多 20 组键值对。格式:"my_name_1": "my_value_1" |
| expiration_offset | 对象 | 可选 | 定义发卡后卡片的有效期持续时间 |
| token | 字符串 | 可选 | 卡片的唯一令牌。长度:1–36 个字符。注意:若未指定,系统将自动生成。一旦设置后无法更新。 |
| user_token | 字符串 | 必填 | 卡片所有者的唯一令牌 |
| fulfillment | 对象 | 可选 | 包含邮寄信息和卡片的物理特征 |
| reissue_pan_from_card_token | 字符串 | 可选 | 重新发行指定卡片,并赋予新卡相同的 PAN 和 PIN(个人识别码),但更换有效期和 CVV2 数字。最大长度:36 个字符 |
| translate_pin_from_card_token | 字符串 | 可选 | 将新创建的卡片分配与指定卡片相同的 PIN。最大长度:36 个字符。注意:两张卡片必须属于同一用户。此外,不能同时设置 reissue_pan_from_card_token。 |
| activation_actions | 对象 | 可选 | 包含卡片激活时要执行的操作。注意:此对象中的字段互斥。 |
| bulk_issuance_token | 字符串 | 可选 | 用于将卡片链接到批量发卡订单的令牌。注意:该字段一旦设置后无法更新。最大长度:36 个字符 |
注意: 有关
expiration_offset、fulfillment和activation_actions对象的详细信息,请参阅 “附加参数和响应字段” 课程。
输入完参数后,点击下方代码框中的“运行”按钮查看输出结果。
1// 导入库 2import fetch from "node-fetch" 3 4// 定义端点 URL 5const endpointUrl = new URL('{{BASE_URL}}cards'); 6 7const tokens = '{{APPLICATION_TOKEN}}:{{ADMIN_ACCESS_TOKEN}}' 8const encoded = Buffer.from(tokens, 'ascii').toString('base64') 9 10const headerParameters = { 11 'Content-Type': 'application/json', 12 'Authorization': `Basic ${encoded}` 13}; 14 15// 定义查询参数 16const queryParameters = new URLSearchParams({ 17 "show_cvv_number": true, 18 "show_pan": true 19}) 20 21// 定义请求体参数 22const bodyParameters = JSON.stringify({ 23 "user_token": "{{USER_TOKEN}}", 24 "card_product_token": "{{CARD_PRODUCT_TOKEN}}", 25 "fulfillment": { 26 "card_personalization": { 27 "text": { 28 "name_line_1": { 29 "value": "" 30 } 31 } 32 }, 33 "shipping": { 34 "recipient_address": { 35 "address1": "9231 Pennsylvania Street Hopewell Junction", 36 "city": "New York City", 37 "state": "New York", 38 "postal_code": "12533", 39 "country": "US", 40 } 41 }, 42 }, 43}); 44 45// 设置 API 调用选项 46const options = { 47 method: "POST", 48 headers: headerParameters, 49 body: bodyParameters 50}; 51 52// 执行 API 调用的函数 53async function createCard() { 54 try { 55 endpointUrl.search = queryParameters; 56 const response = await fetch(endpointUrl, options); 57 // 打印响应 58 printResponse(response); 59 } catch (error) { 60 // 打印错误信息 61 printError(error); 62 } 63} 64 65// 调用函数执行 API 调用 66createCard();
在上述代码框中:
- 第 5 行: 在
endpointURL变量中定义了端点 URL。 - 第 16–19 行: 在
queryParameters变量中将show_cvv_number和show_pan设置为 true。 - 第 22–43 行: 在
bodyParameters变量中添加了user_token、card_product_token和fulfillment。 - 第 47 行: 将请求方法设置为
POST,以创建新卡片。 - 第 56 行: 使用
fetch函数发起 API 调用。
当代码成功执行后,输出将显示包含所有数据字段的完整卡片对象。我们提取 token 字段并保存为 CARD_TOKEN。该值将在本课程后续操作中使用。
如果失败,则会显示相应的错误信息。
响应字段
| 名称 | 类型 | 描述 |
|---|---|---|
| token | 字符串 | 卡片的唯一标识符。允许值:1–36 个字符 |
| user_token | 字符串 | 卡片持有者的唯一标识符。允许值:1–36 个字符 |
| card_product_token | 字符串 | 卡片产品的唯一标识符。允许值:1–36 个字符 |
| pan | 字符串 | 卡片的主账户号码(PAN) |
| expiration | 字符串 | 有效期。格式:MMYY |
| cvv_number | 字符串 | 卡片上印刷的三位数字验证值(CVV2/CVC2) |
| state | 字符串 | 表示卡片状态。允许值:ACTIVE(激活)、SUSPENDED(暂停)、TERMINATED(终止)、UNSUPPORTED(不支持)、UNACTIVATED(未激活)、LIMITED(受限) |
| created_time | 日期时间 | 卡片创建的 UTC 时间。格式:yyyy-MM-ddThh:mm:ssZ |
| last_modified_time | 日期时间 | 资源最后一次更新的 UTC 时间。格式:yyyy-MM-ddThh:mm:ssZ |
创建卡片状态变更
卡片状态变更 指的是设置现有卡片的 state。所有卡片在创建时均为非激活状态,需要手动激活。我们可以通过向 {BASE_URL}/cardtransitions 端点发送 POST 请求来设置现有卡片的状态。
注意: 卡片激活后,可能无法再将其从一个用户转移到另一个用户。
请求参数
| 参数 | 类型 | 分类 | 描述 |
|---|---|---|---|
| card_token | 字符串 | 必填 | 要更改状态的卡片令牌 |
| channel | 字符串 | 必填 | 状态变更所使用的机制。允许值:ADMIN(管理员)、API(接口)、FRAUD(欺诈)、IVR(语音交互)、SYSTEM(系统) |
| state | 字符串 | 必填 | 要设置的新状态。允许值:ACTIVE(激活)、SUSPENDED(暂停)、TERMINATED(终止) |
| token | 字符串 | 可选 | 卡片状态变更的唯一令牌。长度:1–36 个字符。注意:若未指定,系统将自动生成。一旦设置后无法更新。 |
| reason | 字符串 | 可选 | 状态变更的附加说明。最大长度:255 个字符 |
| reason_code | 字符串 | 可选 | 两位数字代码,描述变更原因。允许值:00–31 |
| validations | 对象 | 可选 | 包含用户信息 |
注意: 有关
validations对象以及channel和reason_code值的详细说明,请参阅 “附加参数和响应字段” 课程。
点击下方代码框中的“运行”按钮查看输出结果。
1// 导入库 2import fetch from "node-fetch" 3 4// 定义端点 URL 5const endpointUrl = new URL('{{BASE_URL}}cardtransitions'); 6 7const tokens = '{{APPLICATION_TOKEN}}:{{ADMIN_ACCESS_TOKEN}}' 8const encoded = Buffer.from(tokens, 'ascii').toString('base64') 9 10const headerParameters = { 11 'Content-Type': 'application/json', 12 'Authorization': `Basic ${encoded}` 13}; 14 15// 定义请求体参数 16const bodyParameters = JSON.stringify({ 17 "card_token": "{{CARD_TOKEN}}", 18 "state": "ACTIVE", 19 "channel": "API", 20}); 21 22// 设置 API 调用选项 23const options = { 24 method: "POST", 25 headers: headerParameters, 26 body: bodyParameters 27}; 28 29// 执行 API 调用的函数 30async function createCardTransition() { 31 try { 32 const response = await fetch(endpointUrl, options); 33 // 打印响应 34 printResponse(response); 35 } catch (error) { 36 // 打印错误信息 37 printError(error); 38 } 39} 40 41// 调用函数执行 API 调用 42createCardTransition();
在上述代码框中:
- 第 5 行: 在
endpointURL变量中定义了端点 URL。 - 第 16–20 行: 在
bodyParameters变量中指定card_token,并将state设为ACTIVE,channel设为API。 - 第 24 行: 将请求方法设置为
POST,以创建卡片状态变更。 - 第 32 行: 使用
fetch函数发起 API 调用。
当代码成功执行后,输出将显示包含所有数据字段的完整卡片状态变更对象,其中包括更新后的 state。
如果失败,则会显示相应的错误信息。
响应字段
| 名称 | 类型 | 描述 |
|---|---|---|
| token | 字符串 | 卡片的唯一标识符。允许值:1–36 个字符 |
| user_token | 字符串 | 卡片持有者的唯一标识符。允许值:1–36 个字符 |
| card_product_token | 字符串 | 卡片产品的唯一标识符。允许值:1–36 个字符 |
| card_token | 字符串 | 卡片的唯一标识符。允许值:1–36 个字符 |
| pan | 字符串 | 卡片的主账户号码(PAN) |
| expiration | 字符串 | 有效期。格式:MMYY |
| state | 字符串 | 表示卡片状态。允许值:ACTIVE(激活)、SUSPENDED(暂停)、TERMINATED(终止)、UNSUPPORTED(不支持)、UNACTIVATED(未激活)、LIMITED(受限) |
| created_time | 日期时间 | 卡片创建的 UTC 时间。格式:yyyy-MM-ddThh:mm:ssZ |
| expiration_time | 字符串 | 卡片过期的 UTC 时间。格式:yyyy-MM-ddThh:mm:ssZ |
| last_modified_time | 日期时间 | 资源最后一次更新的 UTC 时间。格式:yyyy-MM-ddThh:mm:ssZ |
更新卡片
我们可以通过向 {BASE_URL}/cards/{token} 端点发送 PUT 请求来更新卡片。路径参数({token})指代要更新的卡片令牌。同时,还需在请求体中指定希望更新的字段。
请求参数
| 参数 | 类型 | 分类 | 描述 |
|---|---|---|---|
| token | 字符串 | 必填 | 要更新的卡片令牌。注意:这是路径参数。 |
| user_token | 字符串 | 可选 | 要关联到卡片的用户令牌 |
| expedite | 布尔值 | 可选 | 请求履约提供商加快卡片处理时设为 true,否则为 false。默认值:false |
| fulfillment | 对象 | 可选 | 包含邮寄信息和卡片的物理特征 |
| metadata | 对象 | 可选 | 将客户提供的元数据添加到卡片中。允许值:最多 20 组键值对。格式:"my_name_1": "my_value_1" |
注意: 我们只能更新
user_token、expedite参数,以及fulfillment和metadata对象的值。有关这些参数的详细信息,请参考前面卡片创建请求参数表。
在以下代码中,我们更新卡片的 metadata。点击下方代码框中的“运行”按钮查看输出结果。
1// 导入库 2import fetch from "node-fetch" 3 4const tokens = '{{APPLICATION_TOKEN}}:{{ADMIN_ACCESS_TOKEN}}' 5const encoded = Buffer.from(tokens, 'ascii').toString('base64') 6 7const cardToken = '{{CARD_TOKEN}}' 8 9// 定义端点 URL 10const endpointUrl = new URL(`{{BASE_URL}}cards/${cardToken}`); 11 12const headerParameters = { 13 'Content-Type': 'application/json', 14 'Authorization': `Basic ${encoded}` 15}; 16 17// 定义请求体参数 18const bodyParameters = JSON.stringify({ 19 "metadata": { 20 "card_purpose": "payment_card" 21 } 22}); 23 24// 设置 API 调用选项 25const options = { 26 method: "PUT", 27 headers: headerParameters, 28 body: bodyParameters 29}; 30 31// 执行 API 调用的函数 32async function updateCard() { 33 try { 34 const response = await fetch(endpointUrl, options); 35 // 打印响应 36 printResponse(response); 37 } catch (error) { 38 // 打印错误信息 39 printError(error); 40 } 41} 42 43// 调用函数执行 API 调用 44updateCard();
在上述代码框中:
- 第 10 行: 在
endpointURL变量中定义了端点 URL 并将cardToken作为路径参数添加。 - 第 18–22 行: 在
bodyParameters变量中输入"card_purpose": "payment_card",将该信息添加到卡片的metadata中。 - 第 26 行: 将请求方法设置为
PUT,以更新卡片。 - 第 34 行: 使用
fetch函数发起 API 调用。
当代码成功执行后,输出将显示对应给定 token 的完整卡片对象,包含所有数据字段,包括已更新的内容。
如果失败,则会显示相应的错误信息。
注意: 有关此 API 调用的响应字段,请参考创建卡片的响应字段表格。