Yandex.Money APIПродолжаем тему по работе с API Яндекс.Денег. Если у вас есть сайт/портал/приложение, написанное на Java, то я хочу вам показать несколько потенциально полезных фич. Хотя даже если у вас нет приложения, можно быстренько написать что-нибудь полезное для себя, — так сказать, 4fun. Под катом вы увидите, как легко и быстро пройти OAuth-аутентификацию, как делать запросы к API Яндекс.Денег и как заплатить за мобильный телефон при помощи Java SDK.

В качестве бонуса я расскажу вам про простые и полезные способы работы без использования API (например, создание одноразовой платежной ссылки для перевода денег на чужой счет) и готовые инструменты по донейшенам и краудфандингу.


Java Yandex.Money API SDK


Мной была написана библиотека для упрощения работы с API Яндекс.Денег. Она умеет проходить OAuth-авторизацию в API, вызывать основные функции (запрос информации о счете, история операций и детальная информация по ним, переводы денег другим пользователям, оплата в магазины). SDK использует библиотеки Gson для работы с json и Apache HTTP client версии 4, но о них я еще упомяну. Библиотека разрабатывалась и запускалась на Java 6.

В качестве примеров я рассмотрю возможность авторизации и оплаты мобильной связи оператора Мегафон, а остальное вы можете собрать сами или при помощи maven из исходников на github'е, задеплоить себе и рассмотреть подробней. Если будете разбираться и что-либо будет непонятно, рекомендую посмотреть в мануале по API или поискать ответ на вопрос в клубе.

Получение токена

Первым делом посмотрим на OAuth-авторизацию. Она была придумана Блейном Куком во время разработки Твиттера. Хорошо, что не Дэвидом Блейном, а то это была бы особая уличная магия спецификация. Итак, этот способ авторизации создан для использования какого-либо сервиса в ваших приложениях, но без ввода и хранения логина и пароля от этого сервиса. Приложение отправляет пользователя с запросом прав к сервису, пользователь там ав��оризуется, одобряет использование сервиса нашим приложением и затем сервис выдает токен доступа к своим функциям. Все просто, но для начинающих разработчиков подобная авторизация обычно становится препятствием. С библиотекой это дело нескольких строк:

    YandexMoney ym = new YandexMoneyImpl(Consts.CLIENT_ID);

    // Указываем необходимые для работы приложения права 
    // на доступ к счету пользователя
    Collection<Permission> scope = new LinkedList<Permission>();
    scope.add(new AccountInfo());
    scope.add(new OperationHistory());   

    codeReqUri = ym.authorizeUri(scope, Consts.REDIRECT_URI);    
    response.sendRedirect(codeReqUri);


При создании объекта ym ему передается идентификатор приложения (он обычно прописывается в константах приложения). Затем проставляем список прав scope и делаем вызов полученного URI. Далее на странице редиректа выполняем обмен временного кода на постоянный токен доступа:

 	String code = request.getParameter("code");
 	ReceiveOAuthTokenResponse resp = ym.receiveOAuthToken(code, Consts.REDIRECT_URI);
 	if (resp.isSuccess()) {
 		out.println("Токен: " + resp.getAccessToken());
 	}


Оплата мобильной связи

Покажу, как оплатить мобильную связь оператора Мегафон. Предварительно пользователю при OAuth-авторизации нужно указать требуемые права для оплаты в магазин. Затем таким же образом создаем объект и вызываем метод, передав ему токен пользователя:

    YandexMoney ym = new YandexMoneyImpl(Consts.CLIENT_ID);    
    try {                        
        Map<String, String> map = new HashMap<String, String>();
        map.put("PROPERTY1", "921");
        map.put("PROPERTY2", "302хххх");
        map.put("sum", "2.50");

        YandexMoneyImpl ym = new YandexMoneyImpl(Consts.CLIENT_ID);
        String token = (String) session.getAttribute("token");
        try {
            RequestPaymentResponse resp = ym.requestPaymentShop(token,
                    "337", map);
            if (resp.isSuccess()) {
                out.println("Идентификатор платежа: " + resp.getPaymentId());
                // Затем надо вызвать метод проведения платежа 
                //(processPaymentByWallet или processPaymentByCard)
                ProcessPaymentResponse paymentResp = ym.processPaymentByWallet(token,
                    resp.getPaymentId());
                ...
            }
    } catch (Exception e) {
        out.println("При выполнении возникла ошибка: " + e.getMessage());
    }


При запросе платежа передаем токен оплачивающего пользователя, шаблон платежа (pattern_id) и Map параметров, определенную для этого магазина. Таким образом можно организовать, к примеру, периодическое пополнение баланса или еще что-нибудь полезное. Примерно так же обстоят дела и с другими вызовами. Более полный пример с большой четверкой операторов можно посмотреть на github'е в файле web/mobile/index.jsp, равно как и другие вызовы.

Использованные библиотеки


В SDK используются библиотеки Gson для работы с json и Apache HTTP client версии 4.

Аpache HTTP client нужен для отправки запросов серверу Яндекс.Денег и получения ответов. Также он гарантирует проверку сертификата удаленного хоста. По умолчанию клиент работает в режиме BrowserCompatHostnameVerifier, что позволяет проверить, является ли хост домена, к которому мы обращаемся, доверенным. Корневой сертификат цепочки сертификатов Яндекс.Денег (GTE CyberTrust Global Root) встроен в платформу java, поэтому отдельно прописывать доверенные сертификаты нет необходимости.

Для парсинга json-ответов я использовал библиотеку Gson. Она имеет несколько вкусных возможностей, которые могут быть полезны и вам. Она позволяет легко и быстро создавать из json-строк эквивалентные java-объекты. Причем можно использовать вложенность объектов друг в друга. Также удобно сделано, что поля, описанные в java-style, могут быть загружены в поля json-style и наоборот. Например, поле sampleFieldNameInJava может быть преобразовано в json'овские sample_field_name_in_java или SampleFieldNameInJava в зависимости от выбранной name policy при создании объекта. Загружает она все через reflection. Простая в использовании и удобная библиотека.

Бонус


Для тех, кого программирование не трогает за душу, покажу несколько простых и полезных инструментов без использования API.

Прямая платежная ссылка

Если для целей вашего проекта использование API излишне, то можно сделать прямую платежную ссылку — пройдя по ней, пользователь окажется на странице с предзаполненной формой перевода денег. Многие о ней спрашивают в клубе Яндекс.Денег на ярушке, может и вам эта фича будет полезна. Но учтите, что это скорее лайфхак, чем документированная фича и использовать ее надо на свой страх и риск. В примере показано (см. файл web/simple/index.jsp), как сформировать подобную ссылку: там 5 основных параметров, отвечающих за заголовок, комментарии и сумму. Остальные служебные, в них можно не вникать. В итоге, после перехода по ссылке мы оказы��аемся на сайте Яндекс.Денег и, чтобы сделать перевод, достаточно лишь ввести платежный пароль.

Также можно создать запрос на перевод, который еще можно редактировать. Для этого можно просто к ссылке
https://money.yandex.ru/direct-payment.xml
добавить желаемые из указанных 5 параметров (sum, receiver и др.). Например,
https://money.yandex.ru/direct-payment.xml?sum=10&receiver=mdv00&destination=my%20comment
В качестве получателя можно указывать, как номер счета, так и эккаунт на Яндексе.

Краудфандинг и донейшены

Для сбора пожертвований существуют специальные инструменты, о которых знают еще не все. Их можно найти во вкладке «Сервисы» главной страницы Яндекс.Денег в разделе «Сбор денег». Помимо этого там много еще полезного, но остановимся на нашей теме.
  • Дай рубльКнопка «Дай рубль», которая встраивается в ваш сайт или блог и позволяет всем поддержать вас и ваше начинание материально.
  • А если вы собираете деньги для достижения каких-либо целей — как, например, гражданин Чистяков (все помнят его знаменитую песню «Человек и кошка — вместе челокошка...») собирает благодарности за свое творчество, — то вам может пригодиться форма для благотворителей. Ну кто сможет пройти мимо формы на «гулянку по поводу сдачи сессии»?
  • Также можно использовать информер «Мой баланс». С его помощью каждый желающий сможет увидеть, сколько денег уже собрано, и помочь по случаю.

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