Major Опубликовано 31 марта, 2017 Поделиться Опубликовано 31 марта, 2017 Ребят, покажите пошагово плиз, как работать с компонентом TInAppPurchase. В Сети ничего не нашел, кроме примера CapitalIAP. ИМХО, это один из важнейших компонентов, где ошибка может дорого стоить. Цитата Ссылка на комментарий
0 Евгений Корепов Опубликовано 1 апреля, 2017 Поделиться Опубликовано 1 апреля, 2017 Вот мой юнит для работы с покупками в приложении: unit UnitInAppPurchase; interface uses // UnitGetDeviceInfo, FMX.InAppPurchase, System.Classes, System.SysUtils, System.Hash; //const // HashMixer = 'p345mcq34mq'; type TBillingEventPurchased = procedure(ASecretKey : String) of object; TBillingEventNotPurchased = procedure of object; TBillingLog = procedure(AMessage : String) of object; TBilling = class private InAppPurchase: TInAppPurchase; FBillingEventPurchased : TBillingEventPurchased; FBillingEventNotPurchased : TBillingEventNotPurchased; FBillingLog : TBillingLog; FNoAdsID : String; FSecretKey : String; FApplicationLicenseKey : String; procedure InAppPurchaseSetupComplete(Sender: TObject); procedure InAppPurchaseProductsRequestResponse(Sender: TObject; const Products: TIAPProductList; const InvalidProductIDs: TStrings); procedure InAppPurchaseError(Sender: TObject; FailureKind: TFailureKind; const ErrorMessage: string); procedure InAppPurchasePurchaseCompleted(Sender: TObject; const ProductID: string; NewTransaction: Boolean); procedure ConsumeComplete(Sender: TObject; const ProductID: string); procedure ConsumeFailed(Sender: TObject; const ProductID, ErrorMessage: string); function GetSecretKey : String; function CheckSecretKey : Boolean; procedure LogMy(AMessage : String); public // Constructor Create(AApplicationLicenseKey, ANoAdsID, ASecretKey : String); constructor Create(AApplicationLicenseKey, ANoAdsID : String); destructor Destroy; procedure CheckPurchase; procedure Purchase; // published property OnPurchased : TBillingEventPurchased read FBillingEventPurchased write FBillingEventPurchased; property OnNotPurchased : TBillingEventNotPurchased read FBillingEventNotPurchased write FBillingEventNotPurchased; property OnPurchasedError : TBillingEventNotPurchased read FBillingEventNotPurchased write FBillingEventNotPurchased; property OnLog : TBillingLog read FBillingLog write FBillingLog; end; implementation //Constructor TBilling.Create(AApplicationLicenseKey, ANoAdsID, ASecretKey : String); Constructor TBilling.Create(AApplicationLicenseKey, ANoAdsID : String); begin FNoAdsID:=ANoAdsID; FApplicationLicenseKey:=AApplicationLicenseKey; // FSecretKey:=ASecretKey; InAppPurchase:=TInAppPurchase.Create(Nil); InAppPurchase.ApplicationLicenseKey:=FApplicationLicenseKey; InAppPurchase.ProductIDs.Add(FNoAdsID); InAppPurchase.OnSetupComplete := InAppPurchaseSetupComplete; InAppPurchase.OnProductsRequestResponse := InAppPurchaseProductsRequestResponse; InAppPurchase.OnError := InAppPurchaseError; InAppPurchase.OnPurchaseCompleted := InAppPurchasePurchaseCompleted; InAppPurchase.OnConsumeCompleted := ConsumeComplete; InAppPurchase.OnConsumeFailed := ConsumeFailed; end; Destructor TBilling.Destroy; begin if Assigned(InAppPurchase) then FreeAndNil(InAppPurchase); inherited; end; procedure TBilling.Purchase; begin try InAppPurchase.PurchaseProduct(FNoAdsID); except LogMy('PurchaseProduct except'); end; end; procedure TBilling.CheckPurchase; begin if CheckSecretKey Then begin LogMy('CheckSecretKey True - Disable Ads'); FSecretKey:=GetSecretKey; if Assigned(OnPurchased) then OnPurchased(FSecretKey); Exit; end; LogMy('CheckSecretKey False - Check InAppPurchase status'); InAppPurchase.SetupInAppPurchase; end; function TBilling.GetSecretKey : String; Var ADeviceIMEI : String; begin // Это был костыль для хранения флага о покупке локально, не оправдал себя и изъят из обращения // ADeviceIMEI:=GetDeviceIMEI; // Result:=System.Hash.THashSHA1.GetHashString(HashMixer+ADeviceIMEI+FNoAdsID); end; function TBilling.CheckSecretKey : Boolean; begin Result:=False; // Result:=FSecretKey.Equals(GetSecretKey); end; procedure TBilling.InAppPurchaseSetupComplete(Sender: TObject); begin LogMy('InAppPurchaseSetupComplete'); try LogMy('InAppPurchase.QueryProducts'); InAppPurchase.QueryProducts; except on E:Exception do LogMy('QueryProducts Exception: '+e.Message); end; end; procedure TBilling.InAppPurchaseProductsRequestResponse(Sender: TObject; const Products: TIAPProductList; const InvalidProductIDs: TStrings); var Product: TProduct; begin LogMy('TMainForm.InAppPurchaseProductsRequestResponse'); LogMy('Start search '+FNoAdsId); LogMy('Products.Count='+Products.Count.ToString); for Product in Products do begin LogMy('Start search '+FNoAdsId); if Product.ProductID = FNoAdsId then begin LogMy('Founded '+FNoAdsId); if InAppPurchase.IsProductPurchased(FNoAdsId) then begin // КУПЛЕНО!!!! LogMy(FNoAdsID+' Yes ProductPurchased'); FSecretKey:=GetSecretKey; if Assigned(OnPurchased) then OnPurchased(FSecretKey); end Else begin LogMy(FNoAdsID+' Not ProductPurchased'); if Assigned(OnNotPurchased) then OnNotPurchased; end; Exit; end; end; LogMy('Product not found - OnNotPurchased'); if Assigned(OnNotPurchased) then OnNotPurchased; LogMy('TMainForm.InAppPurchaseProductsRequestResponse END'); end; procedure TBilling.InAppPurchaseError(Sender: TObject; FailureKind: TFailureKind; const ErrorMessage: string); Var S: String; begin if FailureKind = TFailureKind.ProductsRequest Then S:='ProductsRequest'; if FailureKind = TFailureKind.Purchase Then S:='Purchase'; if Assigned(OnPurchasedError) then OnPurchasedError; LogMy('Purchasing error ('+S+'):'+ErrorMessage); end; procedure TBilling.InAppPurchasePurchaseCompleted(Sender: TObject; const ProductID: string; NewTransaction: Boolean); begin LogMy('TMainForm.InAppPurchasePurchaseCompleted'); if ProductID = FNoAdsID then begin LogMy('HideAndDestroyAds'); FSecretKey:=GetSecretKey; if Assigned(OnPurchased) then OnPurchased(FSecretKey); end; end; procedure TBilling.ConsumeComplete(Sender: TObject; const ProductID: string); begin LogMy('Consume Complete: ' + ProductID); end; procedure TBilling.ConsumeFailed(Sender: TObject; const ProductID, ErrorMessage: string); begin LogMy('Consume Failed: ' + ProductID); end; procedure TBilling.LogMy(AMessage : String); begin if Assigned(OnLog) then OnLog(AMessage); end; end. Использовать вот так: const NoAdsID = 'mysuperapp_remove_ad'; //название товара, тоже что и консоли разработчика ... private Billing : TBilling; procedure BillingEventPurchased(ASecretKey : String); procedure BillingEventNotPurchased; procedure BillingEventPurchasedError; procedure BillingLog(AMessage : String); procedure DisablePurchaseUI; procedure EnablePurchaseUI; ... FormCreate start Var AppLicenseKey : String; ... AppLicenseKey:='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxim8ZGAIhK/FPhpXT0r6MXHYxYi1qcMfIiKOkiBDHcRYgRLK7'; AppLicenseKey:=AppLicenseKey+'********************************************************************************'; AppLicenseKey:=AppLicenseKey+'******************************************************************************'; AppLicenseKey:=AppLicenseKey+'*******************************************************************************'; AppLicenseKey:=AppLicenseKey+'Mgv7JP8A+qcDV3lm4M9OKBgxBRLaejxHd1iH3tsMR8PLkKUUf3yrMW8QIDAQAB'; Billing:=TBilling.Create(AppLicenseKey, NoAdsID); Billing.OnPurchased:=BillingEventPurchased; Billing.OnNotPurchased:=BillingEventNotPurchased; Billing.OnPurchasedError:=BillingEventPurchasedError; Billing.OnLog:=BillingLog; Billing.CheckPurchase; FormCreate stop ... procedure TFormMain.BillingEventPurchased(ASecretKey : String); begin // LogMy('CheckSecretKey True - Disable Ads'); Setting.Flags.AdsShowFlag:=False; DisablePurchaseUI; // удаляет кнопки и прочую фигню предлагающую купить товар (товар в данном случае - Удаление рекламы) HideAndDestroyAds; // удаление рекламы из приложения, так как товар куплен // Setting.SecretKey:=ASecretKey; // SaveFormState; end; procedure TFormMain.BillingEventNotPurchased; begin Setting.Flags.AdsShowFlag:=True; EnablePurchaseUI; ShowAds; end; procedure TFormMain.BillingEventPurchasedError; begin Setting.Flags.AdsShowFlag:=True; // EnablePurchaseUI; ShowAds; end; procedure TFormMain.BillingLog(AMessage : String); begin // Memo.Lines.Insert(0,AMessage); end; procedure TFormMain.DisablePurchaseUI; begin ButtonRemoveAds.Visible:=False; LayoutRemoveAds.Visible:=False; end; procedure TFormMain.EnablePurchaseUI; begin LayoutRemoveAds.Visible:=True; ButtonRemoveAds.Visible:=True; end; Alex7wrt, Rusland и Major 3 Цитата Ссылка на комментарий
0 Major Опубликовано 1 апреля, 2017 Автор Поделиться Опубликовано 1 апреля, 2017 спасибо большое! а с AdMob-ом работали? Цитата Ссылка на комментарий
0 Евгений Корепов Опубликовано 2 апреля, 2017 Поделиться Опубликовано 2 апреля, 2017 18 часов назад, Major сказал: спасибо большое! а с AdMob-ом работали? Да, работал. И кстати соответствующий раздел этого форума содержит всю необходимую вам информацию. Цитата Ссылка на комментарий
0 Major Опубликовано 2 апреля, 2017 Автор Поделиться Опубликовано 2 апреля, 2017 Спасибо за код. А зачем в вашем коде: Var AppLicenseKey : String; ... AppLicenseKey:='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxim8ZGAIhK/FPhpXT0r6MXHYxYi1qcMfIiKOkiBDHcRYgRLK7'; AppLicenseKey:=AppLicenseKey+'********************************************************************************'; AppLicenseKey:=AppLicenseKey+'******************************************************************************'; AppLicenseKey:=AppLicenseKey+'*******************************************************************************'; AppLicenseKey:=AppLicenseKey+'Mgv7JP8A+qcDV3lm4M9OKBgxBRLaejxHd1iH3tsMR8PLkKUUf3yrMW8QIDAQAB'; Чтобы запутать взломщика? Цитата Ссылка на комментарий
0 Евгений Корепов Опубликовано 2 апреля, 2017 Поделиться Опубликовано 2 апреля, 2017 6 минут назад, Major сказал: Спасибо за код. А зачем в вашем коде: Var AppLicenseKey : String; ... AppLicenseKey:='MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxim8ZGAIhK/FPhpXT0r6MXHYxYi1qcMfIiKOkiBDHcRYgRLK7'; AppLicenseKey:=AppLicenseKey+'********************************************************************************'; AppLicenseKey:=AppLicenseKey+'******************************************************************************'; AppLicenseKey:=AppLicenseKey+'*******************************************************************************'; AppLicenseKey:=AppLicenseKey+'Mgv7JP8A+qcDV3lm4M9OKBgxBRLaejxHd1iH3tsMR8PLkKUUf3yrMW8QIDAQAB'; Чтобы запутать взломщика? Хм. Можно и так это рассматривать. Но лучше сначала изучить теоретическую часть покупок в приложении и понять что именно и для чего вы делаете. Копипастить код не поможет. Подробности тут https://www.google.ru/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=покупки+в+приложениях+андроид&* Major 1 Цитата Ссылка на комментарий
0 Major Опубликовано 2 апреля, 2017 Автор Поделиться Опубликовано 2 апреля, 2017 По вашей ссылке в основном открываются программы для взлома. кстати, если не секрет, вашу программу взламывали? Цитата Ссылка на комментарий
0 Евгений Корепов Опубликовано 2 апреля, 2017 Поделиться Опубликовано 2 апреля, 2017 19 минут назад, Major сказал: По вашей ссылке в основном открываются программы для взлома. кстати, если не секрет, вашу программу взламывали? Ссылка это поиск в гугле интересующей вас информации. Думать о жутких хакерах и взломе вашего приложения можно начинать при количестве скачиваний вашего приложения от миллиона и выше. Или при стоимости приложения в несколько тысяч рублей. В противном случае гипотетических хакеров можно не принимать во внимание. Цитата Ссылка на комментарий
Вопрос
Major
Ребят, покажите пошагово плиз, как работать с компонентом TInAppPurchase. В Сети ничего не нашел, кроме примера CapitalIAP.
ИМХО, это один из важнейших компонентов, где ошибка может дорого стоить.
Ссылка на комментарий
7 ответов на этот вопрос
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.