جریان توسعه مجوز «کیف پول Google»

Google Wallet API مجموعه‌ای از انواع مجوز ازپیش تعریف‌شده را ارائه می‌دهد که برای موارد استفاده خاص، مانند کارت‌های هدیه، کارت‌های پرواز، بلیت‌های رویداد، و غیره بهینه‌سازی شده‌اند. نوع مجوز «عمومی» نیز وجود دارد که برای مواردی درنظر گرفته شده است که نوع مجوز خاصی دردسترس نیست.

این مقاله برای آشنایی شما با مراحل اصلی لازم برای ایجاد و صدور مجوز بااستفاده از Google Wallet API است. برای انجام برخی‌از مراحل شرح‌داده‌شده در زیر، روش‌های متعددی وجود دارد، اما در سطح بالا، همه انواع مجوز با دنبال کردن جریان توسعه پایه یکسانی ایجاد می‌شوند.

برای راهنمای گام‌به‌گام دقیق درباره ایجاد مجوز، راهنماهای وب، ایمیل، و پیامک یا برنامه‌های Android را ببینید.

برای چه کاری است

«کلاس مجوزها» مجموعه‌ای از ویژگی‌ها را تعریف می‌کند که در چندین مجوز مشترک هستند، شبیه به الگو. برای مثال، اگر بلیت‌های رویدادی را صادر می‌کنید، «کلاس مجوزها» فیلدهایی را تعریف می‌کند که در همه بلیت‌ها یکسان است، مثل نام، تاریخ، و زمان رویداد.

هر مجوزی که صادر می‌کنید باید به «کلاس مجوزها» ارجاع دهد. همچنین باید برای هر «کلاس مجوز» که ایجاد می‌کنید شناسه یکتایی اختصاص دهید که هنگام ایجاد مجوزها برای ارجاع به آن استفاده می‌شود.

نحوه انجام کار

«کلاس مجوزها» در قالب JSON تعریف می‌شود و می‌توان آن را با Google Wallet REST API، «کیت توسعه نرم‌افزار Android»، یا در «کنسول کسب‌وکار کیف پول Google» ایجاد کرد.

نمایش دادن «کلاس مجوزهای» نمونه

{
  "id": "ISSUER_ID.EVENT_CLASS_ID",
  "issuerName": "[TEST ONLY] Heraldic Event",
  "localizedIssuerName": {
    "defaultValue": {
      "language": "en-US",
      "value": "[TEST ONLY] Heraldic Event"
    }
  },
  "logo": {
    "sourceUri": {
      "uri": "https://images.unsplash.com/photo-1475721027785-f74eccf877e2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=660&h=660"
    },
    "contentDescription": {
      "defaultValue": {
        "language": "en-US",
        "value": "LOGO_IMAGE_DESCRIPTION"
      }
    }
  },
  "eventName": {
    "defaultValue": {
      "language": "en-US",
      "value": "Google Live"
    }
  },
  "venue": {
    "name": {
      "defaultValue": {
        "language": "en-US",
        "value": "Shoreline Amphitheater"
      }
    },
    "address": {
      "defaultValue": {
        "language": "en-US",
        "value": "ADDRESS_OF_THE_VENUE"
      }
    }
  },
  "dateTime": {
    "start": "2023-04-12T11:30"
  },
  "reviewStatus": "UNDER_REVIEW",
  "hexBackgroundColor": "#264750",
  "heroImage": {
    "sourceUri": {
      "uri": "https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1032&h=336"
    },
    "contentDescription": {
      "defaultValue": {
        "language": "en-US",
        "value": "HERO_IMAGE_DESCRIPTION"
      }
    }
  }
}
    

برای چه کاری است

«شیء مجوزها» ویژگی‌های مجوز یکتایی را که برای کاربر خاصی صادر خواهد شد تعریف می‌کند. برای مثال، «شیء مجوزها» برای بلیت رویداد فیلدهایی را تعریف می‌کند که مختص بلیت خاصی است، مثل شماره صندلی یا رمزینه پاسخ‌سریع برای آن بلیت.

وقتی «شیء مجوزها» ایجاد می‌شود، Google Wallet API مجوز جدیدی را ذخیره می‌کند و آن را به حساب «صادرکننده» شما مرتبط می‌کند. این مجوز ذخیره‌شده ترکیبی از ویژگی‌های منحصربه‌فرد «شیء مجوزها» و ویژگی‌های الگوی «کلاس مجوزها» مرتبط است.

همچنین باید به هر «شیء کارت‌ها» یک شناسه یکتا اختصاص دهید که هنگام صدور کارت برای ارجاع به آن استفاده می‌شود.

نحوه انجام کار

«شیء مجوزها» در قالب JSON تعریف می‌شود و می‌توان آن را با Google Wallet REST API یا «کیت توسعه نرم‌افزار Android» ایجاد کرد.

نمایش نمونه «شیء مجوزها»

{
  "id": "ISSUER_ID.OBJECT_ID",
  "classId": "ISSUER_ID.EVENT_CLASS_ID",
  "state": "ACTIVE",
  "seatInfo": {
    "seat": {
      "defaultValue": {
        "language": "en-us",
        "value": "5"
      }
    },
    "row": {
      "defaultValue": {
        "language": "en-us",
        "value": "G"
      }
    },
    "section": {
      "defaultValue": {
        "language": "en-us",
        "value": "40"
      }
    },
    "gate": {
      "defaultValue": {
        "language": "en-us",
        "value": "3A"
      }
    }
  },
  "barcode": {
    "type": "QR_CODE",
    "value": "BARCODE_VALUE",
    "alternateText": ""
  }
}
    

برای چه کاری است

برای صادر کردن مجوز برای کاربر، «کلاس مجوزها» و «شیء مجوزها» باید در «ژتون وب JSON»‏ (JWT) کدگذاری شود. قالب JWT استانداردی رایج و باز برای نمایش ادعاها بین دو طرف است. درصورت صدور مجوز با Google Wallet API، از JWT برای ارسال ادعای اینکه کاربر حق دسترسی به مجوز خاصی را دارد که با حساب «صادرکننده» شما مرتبط است استفاده می‌شود.

وقتی JWT به Google Wallet API ارسال می‌شود، از داده‌های کدبندی‌شده برای شناسایی یک مجوز خاص و صدور آن برای کاربر استفاده می‌شود. اگر مجوز قبلاً صادر شده باشد، این داده‌ها همچنین به Google Wallet API اجازه می‌دهد تا تشخیص دهد که مجوز تکراری است تا بیش‌از یک بار به «کیف پول Google» کاربر اضافه نشود.

نحوه انجام کار

‫JWTها در قالب JSON براساس مشخصات JWT تعریف می‌شوند. برای تعریف JWT جهت صدور مجوز با Google Wallet API، اطلاعات مربوط به مجوزی را که می‌خواهید صادر کنید در ویژگی payload از JWT ارائه می‌دهید.

نمایش نمونه JWT

{
  "iss": "issuer@example.com",
  "aud": "google",
  "typ": "savetowallet",
  "iat": 1696877738,
  "origins": [
    "www.example.com"
  ],
  "payload": {
    "eventTicketObjects": [
      {
        "id": "ISSUER_ID.LOYALTY_OBJECT_SUFFIX"
      }
    ]
  }
}
    

برای چه کاری است

همه JWTهای ارسال‌شده به Google Wallet API برای صدور مجوز باید با اعتبارنامه‌هایی که قبلاً در «کنسول کسب‌وکار کیف پول Google» ارائه کرده‌اید امضا شوند. امضا کردن از اطلاعات کاربری شما برای رمزگذاری JWT استفاده می‌کند تا مجوزهایتان ایمن بماند و به Google Wallet API اجازه می‌دهد اصالت‌سنجی کند که جزئیات مجوز کدگذاری‌شده در آن معتبر است و با حساب «صادرکننده» شما مرتبط است.

نحوه انجام کار

کتابخانه‌های کارخواه «کیف پول Google» و کیت توسعه نرم‌افزار Android روش‌های راحتی برای امضا کردن JWT ارائه می‌دهند. همچنین کتابخانه‌های متن‌باز متعددی وجود دارد که پیچیدگی امضای کد را برای شما مدیریت می‌کنند و می‌توانید از بین آن‌ها انتخاب کنید.

برای کسانی که از Google Wallet REST API برای صدور مجوز استفاده می‌کنند، JWT با کلید «حساب سرویس Google Cloud» امضا می‌شود. برای کسانی که از کیت توسعه نرم‌افزار Android «کیف پول Google» استفاده می‌کنند، کیت توسعه نرم‌افزار به‌طور خودکار امضای JWT را با اثر انگشت SHA-1 گواهی امضای برنامه شما انجام می‌دهد.

برای محافظت از اطلاعات اعتباری‌تان، JWTها باید فقط در سرور شما یا بااستفاده از کیت توسعه نرم‌افزار Android «کیف پول Google» در برنامه‌تان امضا شوند.

نمایش نمونه امضای کد

جاوا

  // Create the JWT as a HashMap object
  HashMap<String, Object> claims = new HashMap<String, Object>();
  claims.put("iss", ((ServiceAccountCredentials) credentials).getClientEmail());
  claims.put("aud", "google");
  claims.put("origins", Arrays.asList("www.example.com"));
  claims.put("typ", "savetowallet");

  // Create the Google Wallet payload and add to the JWT
  HashMap<String, Object> payload = new HashMap<String, Object>();
  payload.put("eventTicketObjects", Arrays.asList(newObject));
  claims.put("payload", payload);

  // Google Cloud service account credentials are used to sign the JWT
  Algorithm algorithm =
      Algorithm.RSA256(
          null, (RSAPrivateKey) ((ServiceAccountCredentials) credentials).getPrivateKey());
  String token = JWT.create().withPayload(claims).sign(algorithm);
        

Node.JS

  // Create the JWT claims
  let claims = {
    iss: this.credentials.client_email,
    aud: 'google',
    origins: ['www.example.com'],
    typ: 'savetowallet',
    payload: {
      eventTicketObjects: [newObject]
    },
  };

  // The service account credentials are used to sign the JWT
  let token = jwt.sign(claims, this.credentials.private_key, { algorithm: 'RS256' });
        

Python

  # Create the JWT claims
  claims = {
      'iss': self.credentials.service_account_email,
      'aud': 'google',
      'origins': ['www.example.com'],
      'typ': 'savetowallet',
      'payload': {
          # The listed classes and objects will be created
          'eventTicketObjects': [new_object]
      }
  }

  # The service account credentials are used to sign the JWT
  signer = crypt.RSASigner.from_service_account_file(self.key_file_path)
  token = jwt.encode(signer, claims).decode('utf-8')
        

برای چه کاری است

وقتی JWT امضاشده را ایجاد کردید، آماده‌اید تا مجوزتان را برای کاربر «کیف پول Google» صادر کنید! این کار با ارائه دکمه یا پیوند «افزودن به کیف پول Google» به کاربر انجام می‌شود. وقتی کاربر روی دکمه یا اَبَرپیوند کلیک می‌کند، JWT امضاشده به Google Wallet API ارسال می‌شود و سپس Google Wallet API آن را بااستفاده از اطلاعات اعتباری ذخیره‌شده شما رمزگشایی می‌کند. پس‌از اصالت‌سنجی امضای JWT، مجوز برای کاربر صادر می‌شود تا آن را در «کیف پول Google» خود ذخیره کند.

نحوه انجام کار

از کیت توسعه نرم‌افزار Android «کیف پول Google» برای برنامه‌های Android بومی استفاده کنید. برای همه پلاتفرم‌های دیگر، ازجمله برنامه‌های iOS، وب تلفن همراه و رایانه، ایمیل، و پیامک، اَبَرپیوندی با قالب https://pay.google.com/gp/v/save/<signed_jwt> ایجاد کنید. درصورت امکان، بهتر است این پیوند را به‌صورت دکمه «افزودن به کیف پول Google» به کاربر ارائه دهید.

برای اطلاعات بیشتر درباره استفاده از دکمه «افزودن به کیف پول Google»، به رهنمودهای نمانام Google Wallet API مراجعه کنید

نشان دادن کد نمونه

  https://pay.google.com/gp/v/save/<signed_jwt>
        

کیت توسعه نرم‌افزار Android

  private lateinit var walletClient: PayClient
  private val addToGoogleWalletRequestCode = 1000
  private lateinit var addToGoogleWalletButton: View

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    walletClient = Pay.getClient(this)
    addToGoogleWalletButton.setOnClickListener {
      walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)
    }
  }
        

وقتی کاربرتان مجوز صادرشده را ذخیره کرد، این مجوز همراه با سایر مجوزهایی که ذخیره کرده است در برنامه «کیف پول Google» او نشان داده می‌شود.

ایجاد کردن «اشیاء مجوز» و «کلاس‌های مجوز» در JWT

«کلاس‌های مجوزها» و «اشیاء مجوزها» را می‌توان ازقبل بااستفاده از Google Wallet REST API یا Android SDK ایجاد کرد. پس‌از ایجاد، از آن‌ها برای صدور مجوز با ارجاع به شناسه آن‌ها استفاده می‌شود.

همچنین می‌توانید «کلاس‌های مجوز» و «اشیاء مجوز» را با جاسازی مستقیم JSON آن‌ها در JWT که برای صدور مجوز به کاربر استفاده می‌شود، «درست به‌موقع» ایجاد کنید. در این روش، «کلاس‌های مجوز» و «اشیاء مجوز» توسط Google Wallet API ایجاد می‌شوند، زمانی که JWT امضاشده بااستفاده از دکمه یا پیوند «افزودن به کیف پول Google» ارسال می‌شود.

برای مثال، در زیر یک JWT با «کلاس مجوزها» و «شیء مجوزها» جدید نشان داده شده است که بااستفاده از ویژگی‌های payload.eventTicketClasses و payload.eventTicketObjects تعریف شده است. توجه داشته باشید که این ویژگی‌ها آرایه هستند، بنابراین می‌توانند یک یا چند «کلاس مجوز» یا «شیء مجوز» را بپذیرند. همچنین می‌توانید فقط یک «شیء مجوزهای» جدید در JWT مشخص کنید که به یک «کلاس مجوزهای» موجود با شناسه آن ارجاع می‌دهد.

نمایش نمونه JWT

  {
    "iss": "issuer@example.com",
    "aud": "google",
    "typ": "savetowallet",
    "iat": 1696877738,
    "origins": [
      "www.example.com"
    ],
    "payload": {
      "eventTicketClasses": [{
        "id": "ISSUER_ID.EVENT_CLASS_ID",
        "issuerName": "[TEST ONLY] Heraldic Event",
        "localizedIssuerName": {
          "defaultValue": {
            "language": "en-US",
            "value": "[TEST ONLY] Heraldic Event"
          }
        },
        "logo": {
          "sourceUri": {
            "uri": "https://images.unsplash.com/photo-1475721027785-f74eccf877e2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=660&h=660"
          },
          "contentDescription": {
            "defaultValue": {
              "language": "en-US",
              "value": "LOGO_IMAGE_DESCRIPTION"
            }
          }
        },
        "eventName": {
          "defaultValue": {
            "language": "en-US",
            "value": "Google Live"
          }
        },
        "venue": {
          "name": {
            "defaultValue": {
              "language": "en-US",
              "value": "Shoreline Amphitheater"
            }
          },
          "address": {
            "defaultValue": {
              "language": "en-US",
              "value": "ADDRESS_OF_THE_VENUE"
            }
          }
        },
        "dateTime": {
          "start": "2023-04-12T11:30"
        },
        "reviewStatus": "UNDER_REVIEW",
        "hexBackgroundColor": "#264750",
        "heroImage": {
          "sourceUri": {
            "uri": "https://images.unsplash.com/photo-1501281668745-f7f57925c3b4?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1032&h=336"
          },
          "contentDescription": {
            "defaultValue": {
              "language": "en-US",
              "value": "HERO_IMAGE_DESCRIPTION"
            }
          }
        }
      }],
      "eventTicketObjects": [{
        "id": "ISSUER_ID.OBJECT_ID",
        "classId": "ISSUER_ID.EVENT_CLASS_ID",
        "state": "ACTIVE",
        "seatInfo": {
          "seat": {
            "defaultValue": {
              "language": "en-us",
              "value": "5"
            }
          },
          "row": {
            "defaultValue": {
              "language": "en-us",
              "value": "G"
            }
          },
          "section": {
            "defaultValue": {
              "language": "en-us",
              "value": "40"
            }
          },
          "gate": {
            "defaultValue": {
              "language": "en-us",
              "value": "3A"
            }
          }
        },
        "barcode": {
          "type": "QR_CODE",
          "value": "BARCODE_VALUE",
          "alternateText": ""
        }
      }]
    }
  }