Jump to content

Анонс 1.13.3.0 и GooglePay


Поздравляем вас с наступающим Новым годом!

Мы благодарим вас за доверие и спасибо, что в этом году вы были с нами. В течении всего года мы прислушивались к вашим пожеланиям и старались сделать все возможное, чтобы наш продукт раз от раза становился удобнее и мощнее.

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

GooglePay - TfgGooglePayClient 

Первая новинка - это новый компонент TfgGooglePayClient оплаты покупок в вашем приложении через платежную систему GooglePay.

Настройка 

Для того, чтобы добавить возможность оплаты покупок в вашем приложении, вам необходимо выполнить первичную настройку на стороне Google https://developers.google.com/pay/api/web/guides/setup?hl=ru

В результате этой настройки вы получите идентификатор продавца Google - MerchantId.

Настройка приложения FGX Native

Для того, чтобы иметь возможность использовать GooglePay в FGX Native приложении, необходимо добавить в манифест Android приложения следующие строчки в любое место внутрь тега <application>:

 1. Версию GooglePlay сервисов. ТОЛЬКО, если вы не используете "Firebase PushNotification", Maps или AdMob.

<meta-data android:name="com.google.android.gms.version" android:value="12451000" />

2. Включить доступ приложения к кошельку:

<meta-data
    android:name="com.google.android.gms.wallet.api.enabled"
    android:value="true" />

3. Указать идентификатор продавца в свойстве "TfgGooglePayClient.MerchantName", полученный на предыдущем шаге.

Проверка возможности оплаты через GooglePay

GooglePay может быть недоступен на устройстве пользователя, поэтому, перед инициированием процесса оплаты, необходимо узнать текущий статус. Это можно сделать через асинхронный метод "TfgGooglePayClient.IsReadyToPayAsync":

uses
  FGX.Payments.GooglePay.Types;

if gpClient.IsSupported then
  gpClient.IsReadyToPayAsync(False, procedure (const AStatus: TfgGooglePayStatus)
    begin
      // Отображаем/Скрываем кнопку оплаты через GooglePay
      btnPay.Visible := AStatus = TfgGooglePayStatus.Available;
    end);

Оплата через GooglePay

Для инициации оплаты необходимо заполнить информацию о проводимой транзакции и воспользоваться асинхронным методом оплаты "TfgGooglePayClient.PayAsync". Минимально необходимая информация в транзакции - это код валюты и цена.

procedure TFormMain.btnPayTap(Sender: TObject);
var
  TransactionInfo: TfgTransactionInfo;
begin
  TransactionInfo := TfgTransactionInfo.Create;
  try
    { Информация о покупке }

    TransactionInfo.SetCurrencyCode('RUB')
                   .SetTotalPrice(100.12);

    gpClient.PayAsync(TransactionInfo);
  finally
    TransactionInfo.Free;
  end;
end;

    Описание полей транзакции, смотрите в исходном коде или на сайте GooglePay.

    По результатам обработки запроса, будет вызвано одно из событий:

    1. "OnPaymentError" - в ходе оплаты произошла ошибка.
    2. "OnPaymentComplete" - пользователь выполнил оплату, токен для проведения оплаты передается в параметрах события.
    3. "OnPaymentCancelled" - пользователь отменил оплату.

    Если платеж прошел успешно, то в событии OnPaymentComplete будет передан JSON ответ, из которого вы можете извлечь необходимую информацию согласно документации:

    procedure TFormMain.gpClientPaymentComplete(Sender: TObject; const AResponse: TJSONValue);
    begin
      mLog.Lines.Add(Format('Completed: AResponse="%s"', [AResponse.Format]));
    end;

    После извлечения платежного токена, вам необходимо провести транзакцию на вашем сервере через ваш банк.

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

      Диагностика и отладка

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

      Все свойства компонента полностью соответствуют оберткам в документации Google Pay. Компонент формирует JSON запрос, который отправляется в нативное API. Вы можете проверить корректность формирования JSON запроса через лог. Для этого необходимо включить расширенное логирование в вашем приложении:

      TfgLog.MinimumLevel := TfgLogLevel.Trace;

      Полезные ссылки:

      TfgApplicationEvents

      При разработке Android приложений и при использовании Android API очень часто требуется отправить запрос другим активностям и получить от них результат. Раньше это решалось через подписку на широковещательные сообщения  FGX.Platform.Android.TfgActivityResultMessage и TfgActivityNewIntentMessage и требовало написать следующий код:

      constructor TFormMain.Create(AOwner: TComponent);
      begin
        inherited;
        TMessageManager.DefaultManager.SubscribeToMessage(TfgActivityResultMessage, ActivityResultHandler);
        TMessageManager.DefaultManager.SubscribeToMessage(TfgActivityNewIntentMessage, ActivityNewIntentHandler);
      end;
      
      destructor TFormMain.Destroy;
      begin
        TMessageManager.DefaultManager.Unsubscribe(TfgActivityNewIntentMessage, ActivityNewIntentHandler);
        TMessageManager.DefaultManager.Unsubscribe(TfgActivityResultMessage, ActivityResultHandler);
        inherited;
      end;
      
      procedure TFormMain.ActivityNewIntentHandler(const Sender: TObject; const M: TMessage);
      var
        Message: TfgActivityNewIntentMessage;
      begin
        TfgAssert.IsClass(M, TfgActivityNewIntentMessage);
      
        Message := TfgActivityNewIntentMessage(M);
        TfgToast.Show(Format('Получен новый интент: intent=%s', [JStringToString(Message.Value.toString)]));
      end;
      
      procedure TFormMain.ActivityResultHandler(const Sender: TObject; const M: TMessage);
      var
        Message: TfgActivityResultMessage;
      begin
        TfgAssert.IsClass(M, TfgActivityResultMessage);
      
        Message := TfgActivityResultMessage(M);
      
        // Intent is available in Message.Data
        TfgToast.Show(Format('Получен результат из другого приложения: requestCode=%d, resultCode=%d', [Message.RequestCode, Message.ResultCode]));
      end;

      Сейчас же мы добавили два новых события "TfgApplicationEvents.OnActivityResult" и "TfgApplicationEvents.OnActivityNewIntent", которые позволяют значительно сократить код и сконцентрироваться только на реализации. 

      procedure TFormMain.fgApplicationEvents1ActivityNewIntent(Sender: TObject; const AIntent: TfgAndroidIntent);
      begin
      {$IFDEF ANDROID}
        TfgToast.Show(Format('Получен новый интент: intent=%s', [JStringToString(AIntent.toString)]));
      {$ENDIF}
      end;
      
      procedure TFormMain.fgApplicationEvents1ActivityResult(Sender: TObject; const ARequestCode, AResultCode: Integer;
        const AIntent: TfgAndroidIntent);
      begin
      {$IFDEF ANDROID}
        TfgToast.Show(Format('Получен результат из другого приложения: requestCode=%d, resultCode=%d', [ARequestCode, AResultCode]));
      {$ENDIF}
      end;

      TfgCollectionView

      Мы провели улучшение контроллера выделения элементов и предоставили больше гибкости в точной настройке поведения. Раньше при режиме выделения  "TfgCollectionViewSelectionMode = SingleSelect" мы не позволяли сбросить выделение элемента повторным нажатием. Это было сделано для возможности реализации меню с отображением текущего выбранного раздела. Однако, для некоторых пользователей такое поведение компонента было нежелательным.

      Теперь мы предлагаем вам самостоятельно решить, как должно работать выделение при помощи новых событий  "TfgCollectionView.OnItemCanSelect" и "TfgCollectionView.OnItemCanDeselect". Данные события вызываются непосредственно до момента установки или снятия выделения и позволяют отменить действие при помощи передаваемого параметра AAllow.

      Так же мы исправили ряд ошибок выделения на платформе iOS, так что теперь процесс выделения работает одинаково на всех платформах.

      ВАЖНО! Теперь по умолчанию компонент позволяет сбросить выделение элемента в режиме SingleSelect

      Заключении

      Желаем вам свершения всего задуманного, интересных проектов и амбициозных целей!

      Спасибо, что вы с нами!

      • Like 4
      • Thanks 3

      5 Comments


      Recommended Comments

      Stas

      Posted

      procedure TFormMain.fgApplicationEvents1ActivityNewIntent(Sender: TObject; const AIntent: TfgAndroidIntent);
      begin
      {$IFDEF ANDROID}
        TfgToast.Show(Format('Получен новый интент: intent=%s', [JStringToString(AIntent.toString)]));
      {$ENDIF}
      end;

      Вот тут непонятно, как Ios к  TfgAndroidIntent  отнесется?

      • Administrators
      Yaroslav Brovin

      Posted

      1 минуту назад, Stas сказал:

      Вот тут непонятно, как Ios к  TfgAndroidIntent  отнесется?

      Там будет просто TObject.

      type
      {$IFDEF ANDROID}
        TfgAndroidIntent = JIntent;
      {$ELSE}
        TfgAndroidIntent = type TObject;
      {$ENDIF}

       

      Stas

      Posted

      Ага, понятно. И эти нововведения будут под елочку, так чтобы между оливье и "Иронией судьбы" посмотреть?

      • Administrators
      Yaroslav Brovin

      Posted

      Релиз сегодня будет, чуть попозже.

      • Like 2
      Stas

      Posted

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

      • Like 1
      • Haha 2
      Guest
      Add a comment...

      ×   Pasted as rich text.   Restore formatting

        Only 75 emoji are allowed.

      ×   Your link has been automatically embedded.   Display as a link instead

      ×   Your previous content has been restored.   Clear editor

      ×   You cannot paste images directly. Upload or insert images from URL.

      • Recently Browsing   0 members

        • No registered users viewing this page.
      ×
      ×
      • Create New...