مسار تطوير بطاقة "محفظة Google"

توفّر Google Wallet API مجموعة محدّدة مسبقًا من أنواع البطاقات التي تم تحسينها لحالات استخدام معيّنة، مثل بطاقات الهدايا وبطاقات صعود الطائرة وتذاكر حضور الفعاليات وغيرها. هناك أيضًا نوع بطاقة عامة مخصّص لحالات الاستخدام التي لا يتوفر فيها نوع بطاقة معيّن.

تهدف هذه المقالة إلى إطلاعك على الخطوات الأساسية المطلوبة لإنشاء بطاقة وإصدارها باستخدام Google Wallet API. هناك طرق متعددة لإنجاز بعض الخطوات المفصّلة أدناه، ولكن بشكل عام، يتم إنشاء جميع أنواع البطاقات باتّباع خطوات التطوير الأساسية نفسها.

للحصول على جولة تفصيلية حول إنشاء بطاقة، يمكنك الاطّلاع على أدلة الويب والرسائل الإلكترونية والرسائل القصيرة أو تطبيقات Android.

الغرض منه

تحدّد فئة البطاقات مجموعة من السمات المشتركة بين بطاقات متعددة، وتكون شبيهة بنموذج معيّن. على سبيل المثال، إذا كنت تصدر تذاكر لحضور حدث، ستحدِّد فئة البطاقات الحقول نفسها على مستوى جميع التذاكر، مثل اسم الحدث وتاريخه ووقته.

يجب أن تشير كل بطاقة تصدرها إلى فئة "البطاقات". يجب أيضًا تحديد معرّف فريد لكل فئة بطاقات تنشئها، ويتم استخدامه للإشارة إليه عند إنشاء البطاقات.

طريقة العمل

يتم تحديد فئة البطاقات بتنسيق JSON، ويمكن إنشاؤها باستخدام Google Wallet REST API أو حزمة تطوير البرامج (SDK) لنظام التشغيل Android أو في Google Wallet Business Console.

عرض أمثلة على فئة البطاقات

{
  "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 أو حزمة تطوير البرامج (SDK) لنظام التشغيل 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 Wallet Business Console. يستخدم التوقيع بيانات الاعتماد لتشفير JWT للحفاظ على أمان بطاقاتك، والسماح لواجهة Google Wallet API بالمصادقة على أنّ تفاصيل البطاقة المرمّزة فيها صالحة ومرتبطة بحساب جهة الإصدار.

طريقة العمل

توفر مكتبات برامج "محفظة Google" وحزمة تطوير البرامج (SDK) لنظام التشغيل Android طرقًا ملائمة لتوقيع ملفات JWT. هناك أيضًا الكثير من المكتبات مفتوحة المصدر المتاحة والتي تتعامل مع تعقيدات توقيع الرمز لكي تختار من بينها.

بالنسبة إلى مستخدمي Google Wallet REST API من أجل إصدار البطاقات، يتم توقيع JWT باستخدام مفتاح حساب على Google Cloud Service. بالنسبة إلى مستخدمي حزمة تطوير البرامج (SDK) لنظام التشغيل Android في "محفظة Google"، تعالج حزمة تطوير البرامج (SDK) تلقائيًا توقيع JWT باستخدام الملف المرجعي SHA-1 لشهادة توقيع التطبيق.

لحماية بيانات الاعتماد، يجب توقيع JWT على خادمك فقط أو باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android في "محفظة Google" في تطبيقك.

عرض مثال لتوقيع الرمز

Java

  // 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، التي تفك تشفيره بعد ذلك باستخدام بيانات الاعتماد المحفوظة. بعد مصادقة توقيع JWT، سيتم إصدار البطاقة للمستخدم لحفظها في "محفظة Google".

طريقة العمل

لإنشاء ميزة "الإضافة إلى محفظة Google" لتطبيق Android، استخدم حزمة تطوير البرامج (SDK) لنظام التشغيل Android في محفظة Google، والتي توفر طرقًا لإنشاء الزر. بالنسبة إلى جميع الأنظمة الأساسية الأخرى، بما في ذلك الويب والبريد الإلكتروني والرسائل النصية، يمكنك إنشاء رابط تشعّبي بالتنسيق https://pay.google.com/gp/v/save/<signed_jwt>. ومن الأفضل كلما أمكن تقديم هذا الرابط إلى المستخدم على أنّه "إضافة إلى محفظة Google" .

لمزيد من المعلومات حول استخدام تطبيق "الإضافة إلى محفظة Google" راجع إرشادات العلامة التجارية في Google Wallet API.

عرض مثال الرمز البرمجي

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

Android SDK

  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

ويمكن إنشاء عناصر الفئات والبطاقات مسبقًا باستخدام واجهة برمجة التطبيقات REST في "محفظة Google" أو حزمة تطوير البرامج (SDK) لنظام التشغيل Android. بعد إنشائها، يتم استخدامها لإصدار البطاقات من خلال الإشارة إلى مستند تعريف الهوية الخاص بها.

يمكنك بدلاً من ذلك إنشاء فئات البطاقات ورموز البطاقات "في الوقت المناسب". عن طريق تضمين 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": ""
        }
      }]
    }
  }