Как стать автором
Обновить
0

Возможна ли анонимная оплата в Apple Pay?

Время на прочтение13 мин
Количество просмотров8.1K

Конечно, нельзя называть Apple Pay анонимным в принципе, хотя бы потому что к ней привязана наша банковская карта. Однако, в момент оплаты что о нас узнаёт продавец? Какие наши персональные данные получает продавец от Apple Pay? Можно ли избежать передачи данных и, тем самым, сделать оплату анонимной в глазах продавца?

Когда мы полагаем, что оплачиваем через Apple Pay, то можем заблуждаться. В зависимости от того что мы приобретаем, используется один из двух механизмов Apple. При покупке любой материальной услуги действительно применяется Apple Pay. Однако, когда мы приобретаем цифровой контент в экосистеме Apple, применяется In-App Purchase. Заказываете Uber через Apple Pay? Верно, это Apple Pay. Оформляете подписку в Apple Music? Это уже In-App Purchase.

Ниже мы рассказываем, какие данные утекают продавцу при оплате внутри приложений. Мы не стали разбирать ситуацию, когда товар оплачивается через POS-терминал, так как она требует отдельного внимания.

Визуально оба механизма очень похожи, но “под капотом” все иначе.
Визуально оба механизма очень похожи, но “под капотом” все иначе.

In-App Purchase

Как уже было сказано выше, данный механизм оплаты используется только для цифрового контента. Электронные книги в Amazon Kindle, дополнительное пространство в Dropbox, скины в PUBG - это всё примеры цифрового контента.

При анализе In-App Purchase выяснилось, что мы анонимны перед продавцом. Некоторая информация о нас все же передается продавцу, но в обезличенном виде. Если мы купим неприличную книгу в LitRes, то разработчики приложения не узнают, что именно мы её приобрели. При условии, что мы не поделились с приложением личной информацией иным путем.

Какие данные передаются продавцу

Ниже представлена таблица, где мы видим какие данные In-App Purchase передает продавцу.

In-App Purchase

Как предотвратить передачу?

Дата первой установки приложения

Никак

Список всех сделанных покупок

Никак

Биллинговая ошибка на стороне клиента (не хватает денег, карта неактивна)

Никак

Дата первой установки приложения

Можно определить, когда мы первый раз скачали приложение, даже если удалим сейчас, но скачаем заново через пол года.

Список всех сделанных покупок

По сути, только дата покупки и что за продукт был приобретен.

Биллинговая ошибка на стороне клиента

Если мы оформим автовозобновляемую подписку, а потом на карте закончатся деньги или карта будет неактивной, то разработчик узнает об этом.

Технические подробности

Спойлер
  1. Приложение предлагает пользователю какой-то контент.

  2. Пользователь инициирует процесс покупки.

  3. Приложение показывает ему окно для совершения транзакции.

  4. После подтверждения приложение какое-то время думает.

  5. Контент предоставлен.

В это время в приложении происходит целая череда событий. Большая часть из них скрыта внутри самой операционной системы, а именно системной библиотеки StoreKit. В результате покупки разработчик получит специальную строку receipt.

Пример receipt

MIITuAYJKoZIhvcNAQcCoIITqTCCE6UCAQExCzAJBgUrDgMCGgUAMIIDWQYJKoZIhvcNAQcBoIIDSgSCA0YxggNCMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQECAQEEAwIBADALAgEDAgEBBAMMATMwCwIBCwIBAQQDAgEAMAsCAQ4CAQEEAwIBWjALAgEPAgEBBAMCAQAwCwIBEAIBAQQDAgEAMAsCARkCAQEEAwIBAzAMAgEKAgEBBAQWAjQrMA0CAQ0CAQEEBQIDAYfPMA0CARMCAQEEBQwDMS4wMA4CAQkCAQEEBgIEUDI1MDAYAgEEAgECBBA04jSbC9Zi5OwSemv9EK8kMBsCAQACAQEEEwwRUHJvZHVjdGlvblNhbmRib3gwHAIBAgIBAQQUDBJjb20uYmVsaXZlLmFwcC5pb3MwHAIBBQIBAQQUJzhO1BR1kxOVGrCEqQLkwvUuZP8wHgIBDAIBAQQWFhQyMDE4LTExLTEzVDE2OjQ2OjMxWjAeAgESAgEBBBYWFDIwMTMtMDgtMDFUMDc6MDA6MDBaMD0CAQcCAQEENedAPSDSwFz7IoNyAPZTI59czwFA1wkme6h1P/iicVNxpR8niuvFpKYx1pqnKR34cdDeJIzMMFECAQYCAQEESfQpXyBVFno5UWwqDFaMQ/jvbkZCDvz3/6RVKPU80KMCSp4onID0/AWet6BjZgagzrXtsEEdVLzfZ1ocoMuCNTOMyiWYS8uJj0YwggFKAgERAgEBBIIBQDGCATwwCwICBqwCAQEEAhYAMAsCAgatAgEBBAIMADALAgIGsAIBAQQCFgAwCwICBrICAQEEAgwAMAsCAgazAgEBBAIMADALAgIGtAIBAQQCDAAwCwICBrUCAQEEAgwAMAsCAga2AgEBBAIMADAMAgIGpQIBAQQDAgEBMAwCAgarAgEBBAMCAQEwDAICBq4CAQEEAwIBADAMAgIGrwIBAQQDAgEAMAwCAgaxAgEBBAMCAQAwEAICBqYCAQEEBwwFdGVzdDIwGwICBqcCAQEEEgwQMTAwMDAwMDQ3MjEwNjA4MjAbAgIGqQIBAQQSDBAxMDAwMDAwNDcyMTA2MDgyMB8CAgaoAgEBBBYWFDIwMTgtMTEtMTNUMTY6NDY6MzFaMB8CAgaqAgEBBBYWFDIwMTgtMTEtMTNUMTY6NDY6MzFaoIIOZTCCBXwwggRkoAMCAQICCA7rV4fnngmNMA0GCSqGSIb3DQEBBQUAMIGWMQswCQYDVQQGEwJVUzETMBEGA1UECgwKQXBwbGUgSW5jLjEsMCoGA1UECwwjQXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMxRDBCBgNVBAMMO0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE1MTExMzAyMTUwOVoXDTIzMDIwNzIxNDg0N1owgYkxNzA1BgNVBAMMLk1hYyBBcHAgU3RvcmUgYW5kIGlUdW5lcyBTdG9yZSBSZWNlaXB0IFNpZ25pbmcxLDAqBgNVBAsMI0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zMRMwEQYDVQQKDApBcHBsZSBJbmMuMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKXPgf0looFb1oftI9ozHI7iI8ClxCbLPcaf7EoNVYb/pALXl8o5VG19f7JUGJ3ELFJxjmR7gs6JuknWCOW0iHHPP1tGLsbEHbgDqViiBD4heNXbt9COEo2DTFsqaDeTwvK9HsTSoQxKWFKrEuPt3R+YFZA1LcLMEsqNSIH3WHhUa+iMMTYfSgYMR1TzN5C4spKJfV+khUrhwJzguqS7gpdj9CuTwf0+b8rB9Typj1IawCUKdg7e/pn+/8Jr9VterHNRSQhWicxDkMyOgQLQoJe2XLGhaWmHkBBoJiY5uB0Qc7AKXcVz0N92O9gt2Yge4+wHz+KO0NP6JlWB7+IDSSMCAwEAAaOCAdcwggHTMD8GCCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwMy13d2RyMDQwHQYDVR0OBBYEFJGknPzEdrefoIr0TfWPNl3tKwSFMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwggEeBgNVHSAEggEVMIIBETCCAQ0GCiqGSIb3Y2QFBgEwgf4wgcMGCCsGAQUFBwICMIG2DIGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wNgYIKwYBBQUHAgEWKmh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmljYXRlYXV0aG9yaXR5LzAOBgNVHQ8BAf8EBAMCB4AwEAYKKoZIhvdjZAYLAQQCBQAwDQYJKoZIhvcNAQEFBQADggEBAA2mG9MuPeNbKwduQpZs0+iMQzCCX+Bc0Y2+vQ+9GvwlktuMhcOAWd/j4tcuBRSsDdu2uP78NS58y60Xa45/H+R3ubFnlbQTXqYZhnb4WiCV52OMD3P86O3GH66Z+GVIXKDgKDrAEDctuaAEOR9zucgF/fLefxoqKm4rAfygIFzZ630npjP49ZjgvkTbsUxn/G4KT8niBqjSl/OnjmtRolqEdWXRFgRi48Ff9Qipz2jZkgDJwYyz+I0AZLpYYMB8r491ymm5WyrWHWhumEL1TKc3GZvMOxx6GUPzo22/SGAGDDaSK+zeGLUR2i0j0I78oGmcFxuegHs5R0UwYS/HE6gwggQiMIIDCqADAgECAggB3rzEOW2gEDANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEmMCQGA1UECxMdQXBwbGUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNVBAMTDUFwcGxlIFJvb3QgQ0EwHhcNMTMwMjA3MjE0ODQ3WhcNMjMwMjA3MjE0ODQ3WjCBljELMAkGA1UEBhMCVVMxEzARBgNVBAoMCkFwcGxlIEluYy4xLDAqBgNVBAsMI0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zMUQwQgYDVQQDDDtBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9ucyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMo4VKbLVqrIJDlI6Yzu7F+4fyaRvDRTes58Y4Bhd2RepQcjtjn+UC0VVlhwLX7EbsFKhT4v8N6EGqFXya97GP9q+hUSSRUIGayq2yoy7ZZjaFIVPYyK7L9rGJXgA6wBfZcFZ84OhZU3au0Jtq5nzVFkn8Zc0bxXbmc1gHY2pIeBbjiP2CsVTnsl2Fq/ToPBjdKT1RpxtWCcnTNOVfkSWAyGuBYNweV3RY1QSLorLeSUheHoxJ3GaKWwo/xnfnC6AllLd0KRObn1zeFM78A7SIym5SFd/Wpqu6cWNWDS5q3zRinJ6MOL6XnAamFnFbLw/eVovGJfbs+Z3e8bY/6SZasCAwEAAaOBpjCBozAdBgNVHQ4EFgQUiCcXCam2GGCL7Ou69kdZxVJUo7cwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAuBgNVHR8EJzAlMCOgIaAfhh1odHRwOi8vY3JsLmFwcGxlLmNvbS9yb290LmNybDAOBgNVHQ8BAf8EBAMCAYYwEAYKKoZIhvdjZAYCAQQCBQAwDQYJKoZIhvcNAQEFBQADggEBAE/P71m+LPWybC+P7hOHMugFNahui33JaQy52Re8dyzUZ+L9mm06WVzfgwG9sq4qYXKxr83DRTCPo4MNzh1HtPGTiqN0m6TDmHKHOz6vRQuSVLkyu5AYU2sKThC22R1QbCGAColOV4xrWzw9pv3e9w0jHQtKJoc/upGSTKQZEhltV/V6WId7aIrkhoxK6+JJFKql3VUAqa67SzCu4aCxvCmA5gl35b40ogHKf9ziCuY7uLvsumKV8wVjQYLNDzsdTJWk26v5yZXpT+RN5yaZgem8+bQp0gF6ZuEujPYhisX4eOGBrr/TkJ2prfOv/TgalmcwHFGlXOxxioK0bA8MFR8wggS7MIIDo6ADAgECAgECMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSYwJAYDVQQLEx1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEWMBQGA1UEAxMNQXBwbGUgUm9vdCBDQTAeFw0wNjA0MjUyMTQwMzZaFw0zNTAyMDkyMTQwMzZaMGIxCzAJBgNVBAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSYwJAYDVQQLEx1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEWMBQGA1UEAxMNQXBwbGUgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOSRqQkfkdseR1DrBe1eeYQt6zaiV0xV7IsZid75S2z1B6siMALoGD74UAnTf0GomPnRymacJGsR0KO75Bsqwx+VnnoMpEeLW9QWNzPLxA9NzhRp0ckZcvVdDtV/X5vyJQO6VY9NXQ3xZDUjFUsVWR2zlPf2nJ7PULrBWFBnjwi0IPfLrCwgb3C2PwEwjLdDzw+dPfMrSSgayP7OtbkO2V4c1ss9tTqt9A8OAJILsSEWLnTVPA3bYharo3GSR1NVwa8vQbP4++NwzeajTEV+H0xrUJZBicR0YgsQg0GHM4qBsTBY7FoEMoxos48d3mVz/2deZbxJ2HafMxRloXeUyS0CAwEAAaOCAXowggF2MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjAfBgNVHSMEGDAWgBQr0GlHlHYJ/vRrjS5ApvdHTX8IXjCCAREGA1UdIASCAQgwggEEMIIBAAYJKoZIhvdjZAUBMIHyMCoGCCsGAQUFBwIBFh5odHRwczovL3d3dy5hcHBsZS5jb20vYXBwbGVjYS8wgcMGCCsGAQUFBwICMIG2GoGzUmVsaWFuY2Ugb24gdGhpcyBjZXJ0aWZpY2F0ZSBieSBhbnkgcGFydHkgYXNzdW1lcyBhY2NlcHRhbmNlIG9mIHRoZSB0aGVuIGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNlLCBjZXJ0aWZpY2F0ZSBwb2xpY3kgYW5kIGNlcnRpZmljYXRpb24gcHJhY3RpY2Ugc3RhdGVtZW50cy4wDQYJKoZIhvcNAQEFBQADggEBAFw2mUwteLftjJvc83eb8nbSdzBPwR+Fg4UbmT1HN/Kpm0COLNSxkBLYvvRzm+7SZA/LeU802KI++Xj/a8gH7H05g4tTINM4xLG/mk8Ka/8r/FmnBQl8F0BWER5007eLIztHo9VvJOLr0bdw3w9F4SfK8W147ee1Fxeo3H4iNcol1dkP1mvUoiQjEfehrI9zgWDGG1sJL5Ky+ERI8GA4nhX1PSZnIIozavcNgs/e66Mv+VNqW2TAYzN39zoHLFbr2g8hDtq6cxlPtdk2f8GHVdmnmbkyQvvY1XGefqFStxu9k0IkEirHDx22TZxeY8hLgBdQqorV2uT80AkHN7B1dSExggHLMIIBxwIBATCBozCBljELMAkGA1UEBhMCVVMxEzARBgNVBAoMCkFwcGxlIEluYy4xLDAqBgNVBAsMI0FwcGxlIFdvcmxkd2lkZSBEZXZlbG9wZXIgUmVsYXRpb25zMUQwQgYDVQQDDDtBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9ucyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQIIDutXh+eeCY0wCQYFKw4DAhoFADANBgkqhkiG9w0BAQEFAASCAQCJ9ctD+7Yi9JWvl6G+1HOcDO++mhY6rc6japAgogVF4xmIdh275IKRwZKpQbhoJmxXwElbMjkIsXks/48/EzuaHDQBNIVowq8qQaSUb3msvfAZfi7RGnhaJGzkXf7azr9NLMxX29R2jTiw2oaz2ri49piggmrGfXsLjWs9zTHWHHNRN1fLTPtcWb95JbQNAiQqlecG5a95/+KZ7+joh8fQwbthe8oWs5Tla0DDwrEoIbc5yjFT18Dln5bndTvWQJZcsbI4xa7BAEhjg/nfwPhaL17tHZeW8mOcCtG9UcuAgXXC6usVAOSocenhmKUR8W+D6F/jhBn0k9ahApPDmpZh

receipt нужен для того, чтобы приложение смогло проверить, действительно ли пользователь совершил эту покупку. Обычно приложение передает эту строку на свой бекенд, а тот - в Apple, чтобы проверить покупку. Apple в ответ на запрос пришлет JSON. Он то нам и нужен:

{
    "receipt": {
        "receipt_type": "ProductionSandbox",
        "adam_id": 0,
        "app_item_id": 0,
        "bundle_id": "com.belive.app.ios",
        "application_version": "3",
        "download_id": 0,
        "version_external_identifier": 0,
        "receipt_creation_date": "2018-11-13 16:46:31 Etc/GMT",
        "receipt_creation_date_ms": "1542127591000",
        "receipt_creation_date_pst": "2018-11-13 08:46:31 America/Los_Angeles",
        "request_date": "2018-11-13 17:10:31 Etc/GMT",
        "request_date_ms": "1542129031280",
        "request_date_pst": "2018-11-13 09:10:31 America/Los_Angeles",
        "original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
        "original_purchase_date_ms": "1375340400000",
        "original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
        "original_application_version": "1.0",
        "in_app": [{
            "quantity": "1",
            "product_id": "test2",
            "transaction_id": "1000000472106082",
            "original_transaction_id": "1000000472106082",
            "purchase_date": "2018-11-13 16:46:31 Etc/GMT",
            "purchase_date_ms": "1542127591000",
            "purchase_date_pst": "2018-11-13 08:46:31 America/Los_Angeles",
            "original_purchase_date": "2018-11-13 16:46:31 Etc/GMT",
            "original_purchase_date_ms": "1542127591000",
            "original_purchase_date_pst": "2018-11-13 08:46:31 America/Los_Angeles",
            "is_trial_period": "false"
        }]
    },
    "status": 0,
    "environment": "Sandbox"
}

Оба примера взяты со StackOverflow.

Чтобы определить дату первой установки, в JSON необходимо найти поле original_purchase_date. Это просто дата, когда приложение было скачано тем самым iTunes аккаунтом, через который совершается покупка.

Поле in_app даст информацию о почти всех покупках, совершенных с этого iTunes аккаунта. Почти, потому что в нем не хранится информация о всех consumable покупках, только о текущей (как в примере выше). Consumable покупки - это покупки, которые можно совершать любое число раз, например, наборы монеток или кристаллов, за которые в приложении можно купить что-то. Все остальные покупки будут всегда храниться в этом поле. Причем, что интересно, если мы сделаем возврат покупки через Apple, то это действие также отобразится в этом массиве. То есть, когда мы в следующий раз придем покупать или восстанавливать покупку, разработчик может узнать не только как часто мы покупаем, но и как часто отменяем покупку.

О нехватке баланса на карте можно будет узнать только в случае продления автовозобновляемой подписки. Эту информацию можно получить через App Store Server Notifications. Это система нотификаций от App Store, на которую подписывается бекенд и может обрабатывать разного рода сообщения. В конкретном случае нас интересует событие DID_FAIL_TO_RENEW

Apple Pay

Просто напомню, что Apple Pay предназначен для материальных товаров и услуг. Примерами могут быть: доставка еды в UberEATS, аренда дома в Airbnb, авиабилеты в Skyscanner.

Исследование Apple Pay показало нам, что продавец однозначно понимает, кто у него покупает товар/услугу. Мы полностью открыты в глазах продавца. Можно ограничить доступ к некоторой информации о себе, но кардинально ситуацию не изменить.

Какие данные передаются продавцу

Ниже представлена таблица, где мы видим какие данные Apple Pay передает продавцу.

До подтверждения оплаты

В момент, когда у нас выскакивает шторка с просьбой подтвердить оплату, продавец уже получает о нас информацию.

Поле

Значение

Как предотвратить передачу?

Тип карты

Дебетовая/Кредитная

Никак

Примерный адрес доставки пользователя

Страна, область, город, почтовый индекс

Исказить или убрать в iOS. Настройки iOS → Wallet и Apple Pay → Параметры оплаты по умолчанию

Примерный платежный адрес пользователя (если не запрошен адрес доставки)

Страна, область, город, почтовый индекс

Исказить или убрать в iOS. Приложение Wallet → Карта → Настройки → Адрес плательщика[1]

Информация о банке эмитенте карты (при наличии договоренности между разработчиком и банком)

Название банка

Никак

После подтверждения оплаты

Как только мы подтверждаем оплату с помощью Face ID, Touch ID или пароля, продавец получает новую порцию данных.

Поле

Значение

Как предотвратить передачу?

Платежная система

Mastercard

Никак

Название карты с последними символами реальной карты

MasterCard 2780

Никак

Точный адрес доставки пользователя

Страна, область, город, почтовый индекс, улица, дом, квартира

До подтверждения оплаты исказить текст в самой шторке

Точный платежный адрес пользователя

Страна, область, город, почтовый индекс, улица, дом, квартира

Исказить или убрать в iOS. Приложение Wallet → Карта → Настройки → Адрес плательщика[1]

Имя Фамилия

Иван Иванов

Исказить или убрать в iOS. Находится там же, где и адрес доставки или платежный адрес.

Номер телефона

+77990001122

1. Либо до подтверждения оплаты исказить текст в самой шторке

2. Либо исказить/убрать в iOS. Настройки → Wallet и Apple Pay → Параметры оплаты по умолчанию[2]

Email

Ivan@gmail.com

От банка-эквайера

После успешной оплаты продавец может запросить дополнительную информацию о нас. Информация запрашивается у того, кто непосредственно обрабатывает нашу оплату (эквайер).

Поле

Значение

Как предотвратить передачу?

IP покупателя

81.18.144.51

Никак

Страна банка эмитента

Россия

Никак 

Имя держателя карты

IVAN IVANOV

Никак 

Срок истечения действия карты

202109

Никак 

Маскированный номер карты, использованной для оплаты (указывается не реальный номер карты, а токен, который был привязан к устройству)

520424**0010

Никак 

Как выглядит подтверждение оплаты

Шторка с подтверждением оплаты может выглядеть по-разному. Все зависит от того, какую информацию о нас запрашивает продавец. Любая запрошенная информация обязательна к заполнению.

Технические подробности

Спойлер

Обратимся к официальной документации и к тестовому приложению и попробуем сделать в нем платеж. Как только приложение показывает окно с суммой и просьбой подтвердить покупку, вызывается метод:

func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didSelectPaymentMethod paymentMethod: PKPaymentMethod, handler completion: @escaping (PKPaymentRequestPaymentMethodUpdate) -> Void)

Eсли при формировании let paymentRequest = PKPaymentRequest() еще запросить requiredShippingContactFields, то вызывается следующее:

func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didSelectShippingContact contact: PKContact, handler completion: @escaping (PKPaymentRequestShippingContactUpdate) -> Void)

Целью этих методов является предоставление разработчикам возможности посчитать стоимость доставки, налогов или сделать скидку пользователям определенных карт. Они то и являются источником данных о типе карты, частичном адресе и информации о банке эмитенте. Если пользователь будет выбирать разные карты или адреса доставки, то эти методы будут вызываться при каждом изменении.

По умолчанию адрес возвращаться не будет, но его можно запросить при показе окна с подтверждением. Сделать это можно, передав в соответствующие поля requiredShippingContactFields и requiredBillingContactFields те данные о пользователе, которые мы хотим получить.

let paymentRequest = PKPaymentRequest()

paymentRequest.requiredShippingContactFields = [
  .postalAddress, 
  .name,
  .phoneNumber,
  .emailAddress
]
paymentRequest.requiredBillingContactFields = [
  .postalAddress,
  .name,
  .phoneNumber,
  .emailAddress
]

Стоит отметить, что если запрашивать requiredBillingContactFields вместе с requiredShippingContactFields, то billingAddress не будет возвращаться до подтверждения покупки.

Если запросить только requiredBillingContactFields, то при выборе карты вызовется метод:

func paymentAuthorizationController(_ controller: PKPaymentAuthorizationController, didSelectPaymentMethod paymentMethod: PKPaymentMethod, handler completion: @escaping (PKPaymentRequestPaymentMethodUpdate) -> Void)

Из объекта paymentMethod: PKPaymentMethod мы получим:

payment.token.paymentMethod.billingAddress givenName nil
payment.token.paymentMethod.billingAddress middleName nil
payment.token.paymentMethod.billingAddress familyName nil
payment.token.paymentMethod.billingAddress                            
														street=, 
                            subLocality=, 
                            city=Москва, 
                            subAdministrativeArea=, 
                            state=Москва, 
                            postalCode=125009, 
                            country=Россия, 
                            countryCode=RU
payment.token.paymentMethod.type 2

А если запросим requiredShippingContactFields, то из метода didSelectShippingContact мы получим:

payment.shippingContact email nil
payment.shippingContact name                        
												namePrefix:                        
												givenName:                        
												middleName:                        
                        familyName:
                        nameSuffix:
                        nickname:
                        phoneticRepresentation: 
                        givenName:
                        middleName:
                        familyName:
payment.shippingContact postalAddress 
                        street=, 
                        subLocality=, 
                        city=Москва, 
                        subAdministrativeArea=, 
                        state=Москва, 
                        postalCode=125009, 
                        country=Россия, 
                        countryCode=RU
payment.shippingContact phoneNumber nil

Пользователь узнает требуются ли эти данные только после того, как окно платежа уже покажется, а данные - уйдут.

Но если пользователь подтвердит покупку - мы получим еще больше:

payment.billingContact
				street=Тверская улица 1 123, 
        subLocality=, 
        city=Москва, 
        subAdministrativeArea=, 
        state=Москва, 
        postalCode=125009, 
        country=Россия, 
        countryCode=RU

Кроме адреса можно запросить еще ФИО, email и номер телефона. Они будут получены после подтверждения оплаты:

payment.shippingContact email ivan@ivanov.ru
payment.shippingContact name 
                        namePrefix:
                        givenName: Иван 
                        middleName:
                        familyName: Иванов 
                        nameSuffix:
                        nickname:
                        phoneticRepresentation: 
                          givenName: Ivan 
                          middleName:
                          familyName: Ivanov
payment.shippingContact phoneNumber stringValue=+77990001122

Но email и номер телефона можно получить только в случае запроса адреса доставки. При запросе адреса платежа такая информация не возвращается:

payment.billingContact email nil
payment.billingContact name 
                       namePrefix:
                       givenName: Иван 
                       middleName:
                       familyName: Иванов 
                       nameSuffix:
                       nickname:
                       phoneticRepresentation: 
                          givenName: Ivan 
                          middleName:
                          familyName: Ivanov
payment.billingContact phoneNumber nil

Также после подтверждения платежа мы получим последние 4 цифры карты, ее платежную систему и название. Ниже пример такой информации для одной из тестовых карт Apple:

paymentMethod.displayName Discover 2780
payment.token.paymentMethod.network PKPaymentNetwork(_rawValue: Discover)

Чтобы разобраться с тем, что можно получить от эквайера, обратимся к документации Сбербанка

Там много разной информации, но самыми интересными выглядят следующие параметры:

  • ip - IP покупателя

  • bankInfo - наименование страны банка-эмитента, если доступно

  • cardAuthInfo - данные карты, привязанной к устройству

    • expiration - срок истечения действия карты

    • pan - маскированный номер карты

      • номер, привязанный к мобильному устройству покупателя и выполняющий функции номера платёжной карты в системе Apple Pay

    • cardholderName - имя держателя карты латиницей, если доступно

Примечания

  1. Если адрес не выбран явно, то будет подтягиваться тот, что указан в адресе доставки.

  2. В этих настройках данные могут быть заданы напрямую, либо подтягиваться из карточки контакта из телефонной книги. Если данные были заданы здесь, то в телефонной книге их нельзя будет найти. Если же данные были введены в телефонной книге, то здесь они будут видны, но удалить их можно только через телефонную книгу. Это будет заметно по подписи под email или телефоном (домашний, рабочий и тд) и по тому, что не будет возможности удалить его.

Теги:
Хабы:
Всего голосов 7: ↑7 и ↓0+7
Комментарии4

Публикации

Информация

Сайт
postuf.com
Дата регистрации
Дата основания
Численность
31–50 человек
Местоположение
О.А.Э.

Истории