diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index dfe0770..0000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f9d9e92 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.pem +vendor/ \ No newline at end of file diff --git a/README.md b/README.md index 626ecd8..6c4cefc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,134 @@ -# passkit-php-quickstart - Quickstart coming soon +PassKit PHP Quickstart +======================= +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://raw.githubusercontent.com/PassKit/passkit-php-grpc-sdk/main/LICENSE) +[![Latest Stable Version](https://poser.pugx.org/passkit/passkit-php-grpc-sdk/v)](https://packagist.org/packages/passkit/passkit-php-grpc-sdk) +### Overview + +This quickstart aims to help get PHP developers up and running with the PassKit SDK as quickly as possible. + +### Prerequisites + +You will need the following: +- PHP 7.0 or higher [Installation Guide](https://grpc.io/docs/languages/php/quickstart/) +- PEAR [Installation Guide](https://pear.php.net/manual/en/installation.php) +- PECL [Mac Installation Guide](https://blackdeerdev.com/install-pecl-pear-on-mac-osx/), [Windows Installation Guide](https://wiki.php.net/internals/windows/stepbystepbuild#building_pecl_extensions) +- Composer [Download Here](https://getcomposer.org/) ([Installation Guide](https://getcomposer.org/download/) ) +- A PassKit account (signup for free at [PassKit](https://app.passkit.com)) +- Your PassKit SDK Credentials (available from the [Developer Tools Page](https://app.passkit.com/app/account/developer-tools)) +- Apple wallet certificate id (for flights only, available from the [certificate page](https://app.passkit.com/app/account/certificates)) + ![ScreenShot](images/certificate.png) + + +### Configuration + +1. Install & Enable the gRPC PHP extension +![ScreenShot](images/pecl.png) + +After installing the gRPC extension, make sure the extension is enabled in your `php.ini` file by typing `php --ini` +![ScreenShot](images/ini.png) + +Make sure that the file has `extension="grpc.so"` and add the line if it doesn't so it matches the screenshot below: +![ScreenShot](images/grpc.png) + +For detailed steps visit the [gRPC PHP quickstart](https://grpc.io/docs/languages/php/quickstart/). + +2. Add bindings to composer +To install the bindings via [Composer](http://getcomposer.org/), add the following to `composer.json`: + +```json +{ + "repositories": [ + { + "type": "git", + "url": "https://github.com/passkit/passkit-php-grpc-sdk.git" + } + ], + "require": { + "passkit/passkit-php-grpc-sdk": "1.1.70" + } +} +``` + +Then run `composer install` + +Manual Installation +Clone the repo and include `autoload.php`: + +```php +require_once('/path/to/passkit-php-grpc-sdk/vendor/autoload.php'); +``` + +3. In the certs folder of the repository add the following three PassKit credential files: + - certificate.pem + - ca-chain.pem + - key.pem + + You can disregard the key-java.pem credentials file as it is not compatible with PHP. + +4. Now we need to decrypt your `key.pem`. At your project root directory, run `cd ./certs` `openssl ec -in key.pem -out key.pem`. +![ScreenShot](images/decrypt-key.png) +For the password use the one-time password that you used for generating the SDK credentials. + +Your `key.pem` file should look like below. + ![ScreenShot](images/decrypted-key.png) + If you do not see `Proc-Type: 4,ENCEYPTED` on line 2, you have successfully decrypted `key.pem`. + +5. Modify the variables with the values for your programs or campaigns in each of the membership, coupons and flights methods. The variables to modify will be at the top of each method. +![ScreenShot](images/variables.png) + +6. To run each method go into the directory, for members `cd membership`, for coupons `cd coupons` and for flights `cd flights`. Then run php plus the name of the method e.g. `php enrol-member.php` to run that method. + +## Examples +### Membership Cards +Follow the steps of the [Quickstart](#quickstart) to get the quickstart up and running. +In the membership folder the methods there are: +- create-program.php - takes a new program name and creates a new program +- create-tier.php - takes the programId of the program just created in the above program, creates a new template (based of default template), creates a tier, and links this tier to the program +- enrol-member.php - takes programId and tierId created by the above methods, and memberDetails, creates a new member record, and sends a welcome email to deliver membership card url + - GetSingleMember() - takes memberId and returns the record of that member +- list-members.php - takes search conditions as pagination object and returns list of member records which match with the conditions +- update-member.php - takes memberId and memberDetails, and updates existing member record +- earn-points.php - takes a programId of an existing program and memberId of existing member to add points to chosen member +- burn-points.php - takes a programId of an existing program and memberId of existing member to use points from a chosen member +- set-points.php - takes a programId of an existing program and memberId of existing member to set the points of a chosen member +- delete-member.php - takes programId, tierId, memberId and memberDetails, deletes an existing member record + + +### Coupons +Follow the steps of the [Quickstart](#quickstart) to get the quickstart up and running. +In the coupons folder the methods are: +- create-campaign.php - takes a new campaign name and creates a new campaign +- create-offer.php - takes a campaignId of the campaign you just created and creates a new template (based of default template), creates an offer, and links this offer to the campaign +- create-coupon.php - takes campaignId and offerId created by the above methods, and couponDetails, creates a new coupon record, and sends a welcome email to deliver coupon card url +- get-single-coupon.php - takes couponId and returns the record of that coupon +- list-coupons.php - takes search conditions as pagination object and returns list of coupon records which match with the conditions +- count-coupons.php - takes search conditions as pagination object and returns the number of coupons who match with the condition +- update-coupon.php - takes a campaignId of an existing campaign and couponId of existing coupon to update that coupon +- redeem-coupon.php - takes a campaignId of an existing campaign and couponId of existing coupon to redeem that coupon +- void-coupon.php - takes the couponId, offerId and campaignId to void an existing coupon +- delete-campaign.php - takes the campaignId to delete an existing campaign + + +### Boarding Passes +#### Issue A Boarding Pass. +Follow the steps of the [Quickstart](#quickstart) to get the quickstart up and running. +In the flights folder the methods are: +- create-template.php - creates the pass template for flights and boarding passes +- create-carrier.php - takes a new carrier code and creates a new carrier +- create-airport.php - takes a new airport code and creates a new airport. +- create-flight.php - takes templateId , from previous method, to use as base template and uses a carrier code, created from previous method, and creates a new flight +- create-flight-designator.php - creates flight designator using flight code +- create-boarding-pass.php - takes templateId, from previous method, and customer details creates a new boarding pass, and sends a welcome email to deliver boarding pass url +- delete-flight.php - takes an existing flight number as well as other details and deletes the flight associated with it +- delete-flight-designator.php - takes an existing flight designation and deletes the flight designator associated with it +- delete-airports.php - takes an existing airport code and deletes the airport associated with it +- delete-carrier.php - takes an existing carrier code and deletes the carrier associated with it + +## Documentation +* [PassKit Membership Official Documentation](https://docs.passkit.io/protocols/member) +* [PassKit Coupons Official Documentation](https://docs.passkit.io/protocols/coupon) +* [PassKit Boarding Passes Official Documentation](https://docs.passkit.io/protocols/boarding) + + +## Getting Help +* [Online chat support](https://passkit.com/) diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..5ede435 --- /dev/null +++ b/composer.json @@ -0,0 +1,49 @@ +{ + "name": "passkit/passkit-php-quickstart", + "description": "PHP gRPC SDK for Apple Wallet and Google Pay Membership / Loyalty / Access Cards, Coupons, Flights & Event-Tickets.", + "keywords": [ + "passkit", + "php", + "sdk", + "api", + "grpc" + ], + "version": "1.0.0", + "homepage": "http://passkit.com", + "license": "MIT", + "authors": [ + { + "name": "PassKit Inc.", + "homepage": "https://passkit.com" + } + ], + "repositories": [ + { + "type": "git", + "url": "https://github.com/passkit/passkit-php-grpc-sdk.git" + } + ], + "require": { + "grpc/grpc": "^v1.42.0", + "google/protobuf": "^v3.21.7", + "passkit/passkit-php-grpc-sdk": "1.1.72" + }, + "autoload": { + "psr-4": { + "Analytics\\": "lib/Analytics", + "Cabin_codes\\": "lib/Cabin_codes", + "Ct\\": "lib/Ct", + "Event_tickets\\": "lib/Event_tickets", + "Flights\\": "lib/Flights", + "Io\\": "lib/Io", + "Members\\": "lib/Members", + "Raw\\": "lib/Raw", + "Scheduler\\": "lib/Scheduler", + "Single_use_coupons\\": "lib/Single_use_coupons", + "GPBMetadata\\Io\\": "lib/GPBMetadata/Io", + "GPBMetadata\\Ct\\": "lib/GPBMetadata/Ct", + "GPBMetadata\\Google\\": "lib/extra/GPBMetadata/Google", + "Google\\Api\\": "lib/extra/google/api" + } + } +} \ No newline at end of file diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..494628b --- /dev/null +++ b/composer.lock @@ -0,0 +1,160 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "c9257d3490aa6d8f7528201e1c512798", + "packages": [ + { + "name": "google/protobuf", + "version": "v3.21.12", + "source": { + "type": "git", + "url": "https://github.com/protocolbuffers/protobuf-php.git", + "reference": "93019df2df0f8c5c01757ef79f3f077d2cb35b65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/93019df2df0f8c5c01757ef79f3f077d2cb35b65", + "reference": "93019df2df0f8c5c01757ef79f3f077d2cb35b65", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": ">=5.0.0" + }, + "suggest": { + "ext-bcmath": "Need to support JSON deserialization" + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Protobuf\\": "src/Google/Protobuf", + "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "proto library for PHP", + "homepage": "https://developers.google.com/protocol-buffers/", + "keywords": [ + "proto" + ], + "support": { + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v3.21.12" + }, + "time": "2022-12-14T14:50:49+00:00" + }, + { + "name": "grpc/grpc", + "version": "1.42.0", + "source": { + "type": "git", + "url": "https://github.com/grpc/grpc-php.git", + "reference": "9fa44f104cb92e924d4da547323a97f3d8aca6d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grpc/grpc-php/zipball/9fa44f104cb92e924d4da547323a97f3d8aca6d4", + "reference": "9fa44f104cb92e924d4da547323a97f3d8aca6d4", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "google/auth": "^v1.3.0" + }, + "suggest": { + "ext-protobuf": "For better performance, install the protobuf C extension.", + "google/protobuf": "To get started using grpc quickly, install the native protobuf library." + }, + "type": "library", + "autoload": { + "psr-4": { + "Grpc\\": "src/lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "gRPC library for PHP", + "homepage": "https://grpc.io", + "keywords": [ + "rpc" + ], + "support": { + "source": "https://github.com/grpc/grpc-php/tree/v1.42.0" + }, + "time": "2021-11-19T08:13:51+00:00" + }, + { + "name": "passkit/passkit-php-grpc-sdk", + "version": "v1.1.72", + "source": { + "type": "git", + "url": "https://github.com/passkit/passkit-php-grpc-sdk.git", + "reference": "ebce339d47a6af89beeaa1c0e901d6a5681e9e70" + }, + "require": { + "google/protobuf": "^v3.21.12", + "grpc/grpc": "^v1.42.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Analytics\\": "lib/Analytics", + "Cabin_codes\\": "lib/Cabin_codes", + "Ct\\": "lib/Ct", + "Event_tickets\\": "lib/Event_tickets", + "Flights\\": "lib/Flights", + "Io\\": "lib/Io", + "Members\\": "lib/Members", + "Raw\\": "lib/Raw", + "Scheduler\\": "lib/Scheduler", + "Single_use_coupons\\": "lib/Single_use_coupons", + "GPBMetadata\\Io\\": "lib/GPBMetadata/Io", + "GPBMetadata\\Ct\\": "lib/GPBMetadata/Ct", + "GPBMetadata\\Google\\": "lib/extra/GPBMetadata/Google", + "Google\\Api\\": "lib/extra/google/api" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PassKit Inc.", + "homepage": "https://passkit.com" + } + ], + "description": "PHP gRPC SDK for Apple Wallet and Google Pay Membership / Loyalty / Access Cards, Coupons, Flights & Event-Tickets.", + "homepage": "http://passkit.com", + "keywords": [ + "api", + "grpc", + "mobile-wallet", + "passkit", + "php", + "sdk", + "wallet" + ], + "time": "2022-12-30T11:06:45+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/coupons/count-coupons.php b/coupons/count-coupons.php new file mode 100644 index 0000000..9387164 --- /dev/null +++ b/coupons/count-coupons.php @@ -0,0 +1,46 @@ + $credentials + ]); + // Set the coupon list request body + $listRequest = new Single_use_coupons\ListRequest(); + $listRequest->setCouponCampaignId($campaignId); + $filter = new Io\FieldFilter(); + $filter->setFilterField("offerId"); + $filter->setFilterValue($offerId); + $filter->setFilterOperator("eq"); + $filterGroup = new Io\FilterGroup(); + $filterGroup->setFieldFilters([$filter]); + $filters = new Io\Filters(); + $filters->setFilterGroups([$filterGroup]); + $listRequest->setFilters($filters); + + + list($result, $status) = $client->countCouponsByCouponCampaign($listRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + echo "Number of coupons " . $result->getTotal() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/create-campaign.php b/coupons/create-campaign.php new file mode 100644 index 0000000..594b662 --- /dev/null +++ b/coupons/create-campaign.php @@ -0,0 +1,35 @@ + $credentials + ]); + // Set the campaign body + $campaign = new Single_use_coupons\CouponCampaign(); + $campaign->setName("Quickstart Campaign"); + $campaign->setStatus([1, 4]); + + list($id, $status) = $client->createCouponCampaign($campaign)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + //You can use the campaignId displayed below for other coupon methods + echo "CampaignId " . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/create-coupon.php b/coupons/create-coupon.php new file mode 100644 index 0000000..60489e8 --- /dev/null +++ b/coupons/create-coupon.php @@ -0,0 +1,50 @@ + $credentials + ]); + // Generates coupon with mandatory fields, more fields can be added, refer to docs.passkit.io and select Coupons for the full list + $coupon = new Single_use_coupons\Coupon(); + $coupon->setCampaignId($campaignId); + $coupon->setOfferId($offerId); + $person = new Io\Person(); + $person->setDisplayName("Loyal Larry"); + $dateOfBirth = new Io\Date(); + $dateOfBirth->setDay(22); + $dateOfBirth->setMonth(6); + $dateOfBirth->setYear(2020); + $person->setDateOfBirth($dateOfBirth); + $person->setEmailAddress($email); + $coupon->setPerson($person); + + list($id, $status) = $client->createCoupon($coupon)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + //You can use the couponId displayed below for other coupon methods + echo "Coupon URL: https://pub1.pskt.io/" . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/create-offer.php b/coupons/create-offer.php new file mode 100644 index 0000000..1371928 --- /dev/null +++ b/coupons/create-offer.php @@ -0,0 +1,78 @@ + $credentials + ]); + + //Create templates client + $templatesclient = new Io\TemplatesClient('grpc.pub1.passkit.io:443', [ + 'credentials' => $credentials + ]); + + // Create the template for the card + // In order to create a tier, we need a pass template id which holds pass design data. Let's use the default pass template for now. + $defaultTemplateRequest = new Io\DefaultTemplateRequest(); + $defaultTemplateRequest->setProtocol(101); + $defaultTemplateRequest->setRevision(1); + list($defaultPassTemplate, $status) = $templatesclient->getDefaultTemplate($defaultTemplateRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + // If you use the default template, you need to set name, description and timezone because these fields are mandatory. + $defaultPassTemplate->setName("Quickstart"); + $defaultPassTemplate->setDescription("quick start sample template"); + $defaultPassTemplate->setTimezone("America/New_York"); + + + list($template, $status) = $templatesclient->createTemplate($defaultPassTemplate)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + // Set the offer body + $offer = new Single_use_coupons\CouponOffer(); + $offer->setId("base"); + $offer->setCampaignId($campaignId); + $offer->setBeforeRedeemPassTemplateId($template->getId()); + $offer->setOfferTitle("BaseOffer"); + $offer->setOfferShortTitle("BaseOffer"); + $offer->setOfferDetails("Base offer"); + $date = new DateTime(); + $date->setDate(2023, 6, 24); + $startdate = new Timestamp(); + $startdate->setSeconds($date->getTimestamp()); + $enddate = new Timestamp(); + $date->setDate(2023, 6, 28); + $enddate->setSeconds($date->getTimestamp()); + $offer->setIssueStartDate($startdate); + $offer->setIssueEndDate($enddate); + + list($id, $status) = $client->createCouponOffer($offer)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + //You can use the offerId displayed below for other coupon methods + echo "Offer created: " . $offer->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/delete-campaign.php b/coupons/delete-campaign.php new file mode 100644 index 0000000..08e7c09 --- /dev/null +++ b/coupons/delete-campaign.php @@ -0,0 +1,35 @@ + $credentials + ]); + // Set the delete campaign body + $id = new Io\Id(); + $id->setId($campaignId); + + list($id, $status) = $client->deleteCouponCampaign($id)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + echo "Campaign deleted. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/get-single-coupon.php b/coupons/get-single-coupon.php new file mode 100644 index 0000000..630ce02 --- /dev/null +++ b/coupons/get-single-coupon.php @@ -0,0 +1,39 @@ + $credentials + ]); + // Set the coupon id + $id = new Io\Id(); + $id->setId($couponId); + + list($id, $status) = $client->getCouponById($id)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Coupon Status: " . $id->getStatus() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/list-coupons.php b/coupons/list-coupons.php new file mode 100644 index 0000000..91e0c04 --- /dev/null +++ b/coupons/list-coupons.php @@ -0,0 +1,38 @@ + $credentials + ]); + // Set the coupon list request + $listRequest = new Single_use_coupons\ListRequest(); + $listRequest->setCouponCampaignId($campaignId); + + $call = $client->listCouponsByCouponCampaign($listRequest); + $coupons = $call->responses(); + foreach ($coupons as $coupon) { + echo $coupon->getId() . "\n"; + } + + echo "/n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/redeem-coupon.php b/coupons/redeem-coupon.php new file mode 100644 index 0000000..89d128e --- /dev/null +++ b/coupons/redeem-coupon.php @@ -0,0 +1,41 @@ + $credentials + ]); + // Set the coupon to redeem + $coupon = new Single_use_coupons\Coupon(); + $coupon->setCampaignId($campaignId); + $coupon->setId($couponId); + $coupon->setStatus(1); + + + list($id, $status) = $client->redeemCoupon($coupon)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Coupon: " . $id->getId() . " has been redeemed. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/update-coupon.php b/coupons/update-coupon.php new file mode 100644 index 0000000..6b06bcf --- /dev/null +++ b/coupons/update-coupon.php @@ -0,0 +1,43 @@ + $credentials + ]); + // Set the coupon to update as well as updated info + $coupon = new Single_use_coupons\Coupon(); + $coupon->setCampaignId($campaignId); + $coupon->setId($couponId); + $person = new Io\Person(); + $person->setDisplayName("Highroller Harry"); //Changes customers name + $coupon->setPerson($person); + + + list($id, $status) = $client->updateCoupon($coupon)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Coupon: " . $id->getId() . " has been updated. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/coupons/void-coupon.php b/coupons/void-coupon.php new file mode 100644 index 0000000..90661e8 --- /dev/null +++ b/coupons/void-coupon.php @@ -0,0 +1,40 @@ + $credentials + ]); + // Set the void coupon body + $coupon = new Single_use_coupons\Coupon(); + $coupon->setCampaignId($campaignId); + $coupon->setOfferId($offerId); + $coupon->setId($couponId); + + list($id, $status) = $client->voidCoupon($coupon)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Coupon has been voided. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/create-airport.php b/flights/create-airport.php new file mode 100644 index 0000000..e7fdca1 --- /dev/null +++ b/flights/create-airport.php @@ -0,0 +1,58 @@ + $credentials + ]); + + // Set the departure airport body + $airport = new Flights\Port(); + $airport->setIataAirportCode("YY4"); + $airport->setIcaoAirportCode("YYYY"); + $airport->setCityName("London"); + $airport->setAirportName("London"); + $airport->setCountryCode("IE"); + $airport->setTimezone("Europe/London"); + + + list($id, $status) = $client->createPort($airport)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo $id->getId() . "/n"; + // Set the arrival airport body if does not currently exist + $airport = new Flights\Port(); + $airport->setIataAirportCode("ADP"); + $airport->setIcaoAirportCode("ADPY"); + $airport->setCityName("London"); + $airport->setAirportName("London"); + $airport->setCountryCode("IE"); + $airport->setTimezone("Europe/London"); + + + list($id, $status) = $client->createPort($airport)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Airport created with code " . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/create-boarding-pass.php b/flights/create-boarding-pass.php new file mode 100644 index 0000000..763679a --- /dev/null +++ b/flights/create-boarding-pass.php @@ -0,0 +1,56 @@ + $credentials + ]); + + // Set the boarding pass body + $boardingPass = new Flights\BoardingPassRecord(); + $boardingPass->setCarrierCode($carrierCode); + $boardingPass->setBoardingPoint("YYY"); + $boardingPass->setDeplaningPoint("LHR"); + $boardingPass->setOperatingCarrierPNR(""); + $boardingPass->setFlightNumber("12345"); + $boardingPass->setSequenceNumber(2); + $passenger = new Flights\Passenger(); + $passengerDetails = new Io\Person(); + $passengerDetails->setSurname("Smith"); + $passengerDetails->setForename("Bailey"); + $passengerDetails->setDisplayName("Bailey"); + $passengerDetails->setEmailAddress($emailAddress); + $passenger->setPassengerDetails($passengerDetails); + $boardingPass->setPassenger($passenger); + $departureDate = new Io\Date(); + $departureDate->setDay(28); + $departureDate->setMonth(7); + $departureDate->setYear(2022); + $boardingPass->setDepartureDate($departureDate); + + list($id, $status) = $client->createBoardingPass($boardingPass)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "https://pub1.pskt.io/" . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/create-carrier.php b/flights/create-carrier.php new file mode 100644 index 0000000..5d94916 --- /dev/null +++ b/flights/create-carrier.php @@ -0,0 +1,39 @@ + $credentials + ]); + + // Set the carrier body + $carrier = new Flights\Carrier(); + $carrier->setIataCarrierCode("YY"); + $carrier->setAirlineName("PassKit Air"); + $carrier->setPassTypeIdentifier($appleCertificate); + + list($id, $status) = $client->createCarrier($carrier)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Carrier created with code: " . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/create-flight-designator.php b/flights/create-flight-designator.php new file mode 100644 index 0000000..12708ef --- /dev/null +++ b/flights/create-flight-designator.php @@ -0,0 +1,65 @@ + $credentials + ]); + + // Set the flight body + $flightDesignator = new Flights\FlightDesignator(); + $flightDesignator->setCarrierCode($carrierCode); + $flightDesignator->setFlightNumber("12345"); + $flightDesignator->setRevision(0); + $flightDesignator->setSchedule("ADP"); + $flightDesignator->setPassTemplateId($templateId); + $flightDesignator->setOrigin("YYY"); + $flightDesignator->setOrigin("ADP"); + $flightTimes = new Flights\FlightTimes(); + $boardingTime = new Io\Time(); + $boardingTime->setHour(13); + $scheduledDeparture = new Io\Time(); + $scheduledDeparture->setHour(13); + $scheduledArrival = new Io\Time(); + $scheduledArrival->setHour(14); + $gateTime = new Io\Time(); + $gateTime->setHour(13); + $gateTime->setMinute(30); + $flightTimes->setBoardingTime($time); + $flightTimes->setScheduledDepartureTime($scheduledDeparture); + $flightTimes->setScheduledArrivalTime($scheduledArrival); + $flightTimes->setGateClosingTime($gateTime); + $schedule = new Flights\FlightSchedule(); + $schedule->setMonday($flightTimes); + $schedule->setTuesday($flightTimes); + $schedule->setWednesday($flightTimes); + $schedule->setThursday($flightTimes); + $schedule->setFriday($flightTimes); + $schedule->setSaturday($flightTimes); + $schedule->setSunday($flightTimes); + $flightDesignator->setSchedule($schedule); + + list($id, $status) = $client->createFlightDesignator($flightDesignator)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Flight designator created with code: " . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/create-flight.php b/flights/create-flight.php new file mode 100644 index 0000000..3744fe4 --- /dev/null +++ b/flights/create-flight.php @@ -0,0 +1,49 @@ + $credentials + ]); + + // Set the flight body + $flight = new Flights\Flight(); + $flight->setCarrierCode($carrierCode); + $flight->setFlightNumber("12345"); + $flight->setBoardingPoint("YY4"); + $flight->setDeplaningPoint("ADP"); + $departureDate = new DateTime(); + $departureDate->setDate(2022, 6, 28); + $flight->setDepartureDate($departureDate->getTimestamp()); + $departureTime = new Io\Time(); + $departureTime->setHour(13); + $departureTime->setMinute(00); + $departureTime->setSecond(00); + $flight->setScheduledDepartureTime($departureTime); + $flight->setPassTemplateId($templateId); + + list($id, $status) = $client->createFlight($flight)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Flight created with code: " . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/create-template.php b/flights/create-template.php new file mode 100644 index 0000000..2caf426 --- /dev/null +++ b/flights/create-template.php @@ -0,0 +1,51 @@ + $credentials + ]); + + // Create the template for the card + // In order to create a tier, we need a pass template id which holds pass design data. Let's use the default pass template for now. + $defaultTemplateRequest = new Io\DefaultTemplateRequest(); + $defaultTemplateRequest->setProtocol(3); + $defaultTemplateRequest->setRevision(1); + $defaultPassTemplate = new Io\PassTemplate(); + + $defaultPassTemplate->$templatesclient->getDefaultTemplate($defaultTemplateRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + // If you use the default template, you need to set name, description and timezone because these fields are mandatory. + $defaultPassTemplate->setName("Quickstart"); + $defaultPassTemplate->setDescription("quick start sample template"); + $defaultPassTemplate->setTimezone("America/New_York"); + + + list($id, $status) = $templatesclient->createTemplate($defaultPassTemplate)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + //You can use the templateId displayed below for other flight methods + echo "TemplateId: " . $defaultPassTemplate->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/delete-airport.php b/flights/delete-airport.php new file mode 100644 index 0000000..162574d --- /dev/null +++ b/flights/delete-airport.php @@ -0,0 +1,35 @@ + $credentials + ]); + + // Set the airport code body + $airport = new Flights\AirportCode(); + $airport->setAirportCode("YYY"); + + list($id, $status) = $client->deletePort($airport)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Airport deleted. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/delete-carrier.php b/flights/delete-carrier.php new file mode 100644 index 0000000..4ab8560 --- /dev/null +++ b/flights/delete-carrier.php @@ -0,0 +1,37 @@ + $credentials + ]); + + // Set the carrier code body + $carrier = new Flights\CarrierCode(); + $carrier->setCarrierCode($carrier); + + list($id, $status) = $client->deleteCarrier($carrier)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Carrier deleted. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/delete-flight-designator.php b/flights/delete-flight-designator.php new file mode 100644 index 0000000..290e7cf --- /dev/null +++ b/flights/delete-flight-designator.php @@ -0,0 +1,39 @@ + $credentials + ]); + + // Set the flight designator request body + $flightDesignator = new Flights\FlightDesignatorRequest(); + $flightDesignator->setCarrierCode($carrierCode); + $flightDesignator->setFlightNumber("12345"); + $flightDesignator->setRevision(0); + + list($id, $status) = $client->deleteFlightDesignator($flightDesignator)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Flight designator deleted. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/flights/delete-flight.php b/flights/delete-flight.php new file mode 100644 index 0000000..104f503 --- /dev/null +++ b/flights/delete-flight.php @@ -0,0 +1,47 @@ + $credentials + ]); + + // Set the flight request body + $flight = new Flights\FlightRequest(); + $flight->setCarrierCode($carrierCode); + $flight->setFlightNumber("12345"); + $flight->setBoardingPoint("YY4"); + $flight->setDeplaningPoint("ADP"); + $departureDate = new DateTime(); + $departureDate->setDate(2022, 6, 28); + $flight->setDepartureDate($departureDate->getTimestamp()); + $departureTime = new Io\Time(); + $departureTime->setHour(13); + $departureTime->setMinute(00); + $departureTime->setSecond(00); + + list($id, $status) = $client->deleteFlight($flight)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Flight deleted. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/images/certificate.png b/images/certificate.png new file mode 100644 index 0000000..a8ecb68 Binary files /dev/null and b/images/certificate.png differ diff --git a/images/decrypt-key.png b/images/decrypt-key.png new file mode 100644 index 0000000..4abe6a8 Binary files /dev/null and b/images/decrypt-key.png differ diff --git a/images/decrypted-key.png b/images/decrypted-key.png new file mode 100644 index 0000000..354e519 Binary files /dev/null and b/images/decrypted-key.png differ diff --git a/images/grpc.png b/images/grpc.png new file mode 100644 index 0000000..c1e8c45 Binary files /dev/null and b/images/grpc.png differ diff --git a/images/ini.png b/images/ini.png new file mode 100644 index 0000000..b891484 Binary files /dev/null and b/images/ini.png differ diff --git a/images/pecl.png b/images/pecl.png new file mode 100644 index 0000000..7bf300c Binary files /dev/null and b/images/pecl.png differ diff --git a/images/variables.png b/images/variables.png new file mode 100644 index 0000000..a0d20a5 Binary files /dev/null and b/images/variables.png differ diff --git a/membership/burn-points.php b/membership/burn-points.php new file mode 100644 index 0000000..ab7587e --- /dev/null +++ b/membership/burn-points.php @@ -0,0 +1,43 @@ + $credentials + ]); + + // Set the Member body + //The points to use to should be from whatever point scheme is used on your card e.g. Points, TierPoints or SecondaryPoints + $memberPointsRequest = new \Members\EarnBurnPointsRequest(); + $memberPointsRequest->setId($memberId); + $memberPointsRequest->setPoints(2000); + $memberPointsRequest->setSecondaryPoints(1000); + $memberPointsRequest->setTierPoints(100); + + list($result, $status) = $client->burnPoints($memberPointsRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Burned points of member: " . $result->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/create-program.php b/membership/create-program.php new file mode 100644 index 0000000..f8a88af --- /dev/null +++ b/membership/create-program.php @@ -0,0 +1,36 @@ + $credentials + ]); + // Set the program body + $program = new Members\Program(); + $program->setName("Quickstart Program"); + $program->setStatus([1, 4]); + + list($id, $status) = $client->createProgram($program)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + //You can use the programId displayed below for other membership methods + echo "ProgramId " . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/create-tier.php b/membership/create-tier.php new file mode 100644 index 0000000..e86f6db --- /dev/null +++ b/membership/create-tier.php @@ -0,0 +1,72 @@ + $credentials + ]); + + //Create templates client + $templatesclient = new Io\TemplatesClient('grpc.pub1.passkit.io:443', [ + 'credentials' => $credentials + ]); + + // Create the template for the card + // In order to create a tier, we need a pass template id which holds pass design data. Let's use the default pass template for now. + $defaultTemplateRequest = new Io\DefaultTemplateRequest(); + $defaultTemplateRequest->setProtocol(100); + $defaultTemplateRequest->setRevision(1); + list($defaultPassTemplate, $status) = $templatesclient->getDefaultTemplate($defaultTemplateRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + // If you use the default template, you need to set name, description and timezone because these fields are mandatory. + $defaultPassTemplate->setName("Quickstart"); + $defaultPassTemplate->setDescription("quick start sample template"); + $defaultPassTemplate->setTimezone("America/New_York"); + + + list($template, $status) = $templatesclient->createTemplate($defaultPassTemplate)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + // Set the tier body + $tier = new Members\Tier(); + $tier->setId("silver"); + $tier->setName("Base Tier2"); + $tier->setPassTemplateId($template->getId()); + $tier->setProgramId($programId); + $tier->setTierIndex(2); + $tier->setTimezone("Europe/London"); + + + list($id, $status) = $client->createTier($tier)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + //You can use the tierId displayed below for other membership methods + echo "Tier created: " . $tier->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/delete-member.php b/membership/delete-member.php new file mode 100644 index 0000000..e552436 --- /dev/null +++ b/membership/delete-member.php @@ -0,0 +1,37 @@ + $credentials + ]); + + // Set the Member body + $member = new Members\Member(); + $member->setId($memberId); + + list($result, $status) = $client->deleteMember($member)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + echo "Member deleted. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/earn-points.php b/membership/earn-points.php new file mode 100644 index 0000000..0205475 --- /dev/null +++ b/membership/earn-points.php @@ -0,0 +1,45 @@ + $credentials + ]); + + // Set the Member points body + //The points to add to should be whatever point scheme is used on your card e.g. Points, TierPoints or SecondaryPoints + $memberPointsRequest = new \Members\EarnBurnPointsRequest(); + $memberPointsRequest->setId($memberId); + $memberPointsRequest->setPoints(2000); + $memberPointsRequest->setSecondaryPoints(1000); + $memberPointsRequest->setTierPoints(100); + + + list($result, $status) = $client->earnPoints($memberPointsRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Member: " . $result->getId() . " has " . $result->getPoints() . " points. \n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/enrol-member.php b/membership/enrol-member.php new file mode 100644 index 0000000..837f456 --- /dev/null +++ b/membership/enrol-member.php @@ -0,0 +1,51 @@ + $credentials + ]); + + // Set the Member body + $member = new Members\Member(); + $member->setProgramId($programId); + $member->setTierId($tierId); + + $person = new Io\Person(); + $person->setDisplayName("Peter Pan"); + $dateOfBirth = new Io\Date(); + $dateOfBirth->setDay(22); + $dateOfBirth->setMonth(6); + $dateOfBirth->setYear(2020); + $person->setDateOfBirth($dateOfBirth); + $person->setEmailAddress($email); + $member->setPerson($person); + + list($id, $status) = $client->enrolMember($member)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + //You can use the memberId displayed below for other membership methods + echo "Pass URL: " . "https://pub1.pskt.io/" . $id->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/list-members.php b/membership/list-members.php new file mode 100644 index 0000000..e3b3d20 --- /dev/null +++ b/membership/list-members.php @@ -0,0 +1,36 @@ + $credentials + ]); + + // Set the Member body + $listRequest = new Members\ListRequest(); + $listRequest->setProgramId($programId); + + $call = $client->listMembers($listRequest); + $members = $call->responses(); + foreach ($members as $member) { + echo $member->getId() . "\n"; + } +} catch (Exception $e) { + echo $e; +} diff --git a/membership/set-points.php b/membership/set-points.php new file mode 100644 index 0000000..f29e58b --- /dev/null +++ b/membership/set-points.php @@ -0,0 +1,42 @@ + $credentials + ]); + + // Set the Member body + $memberPointsRequest = new \Members\SetPointsRequest(); + $memberPointsRequest->setId($memberId); + $memberPointsRequest->setPoints(2000); + //$memberPointsRequest->setSecondaryPoints(1000); + //$memberPointsRequest->setTierPoints(100); + + list($result, $status) = $client->setPoints($memberPointsRequest)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Set points of member " . $result->getId() . "\n"; +} catch (Exception $e) { + echo $e; +} diff --git a/membership/update-member.php b/membership/update-member.php new file mode 100644 index 0000000..302fa11 --- /dev/null +++ b/membership/update-member.php @@ -0,0 +1,42 @@ + $credentials + ]); + + // Set the Member body + $member = new Members\Member(); + $member->setId($memberId); + $member->setProgramId($programId); + $member->setTierId($tierId); + $member->setPoints(2001); + + list($result, $status) = $client->updateMember($member)->wait(); + if ($status->code !== 0) { + throw new Exception(sprintf('Status Code: %s, Details: %s, Meta: %s', $status->code, $status->details, var_dump($status->metadata))); + } + + echo "Updated member " . $result->getId() . "\n"; +} catch (Exception $e) { + echo $e; +}