├── .gitignore ├── .gitmodules ├── LICENSE ├── OpenIAB-Unity-Plugin.iml ├── OpenIAB_manual.odt ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── unity_plugin ├── .gitignore ├── README.md ├── build.gradle ├── gradle.properties ├── libs ├── classes.jar └── in-app-purchasing-2.0.0.jar ├── openiab-unity-test.keystore ├── openiab.keystore ├── project.properties ├── src └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── onepf │ │ └── openiab │ │ ├── UnityPlugin.java │ │ └── UnityProxyActivity.java │ └── res │ ├── layout │ └── main.xml │ └── values │ └── strings.xml ├── unity_src ├── .gitignore ├── Assets │ ├── .gitignore │ ├── AssetStoreTools.meta │ ├── AssetStoreTools │ │ ├── Editor.meta │ │ ├── Editor │ │ │ ├── AssetStoreTools.dll │ │ │ ├── AssetStoreTools.dll.meta │ │ │ ├── AssetStoreToolsExtra.dll │ │ │ ├── AssetStoreToolsExtra.dll.meta │ │ │ ├── DroidSansMono.ttf │ │ │ ├── DroidSansMono.ttf.meta │ │ │ ├── icon.png │ │ │ └── icon.png.meta │ │ ├── Labels.asset │ │ └── Labels.asset.meta │ ├── OpenIAB-demo.meta │ ├── OpenIAB-demo │ │ ├── OpenIAB-demo.unity │ │ ├── OpenIAB-demo.unity.meta │ │ ├── OpenIABTest.cs │ │ └── OpenIABTest.cs.meta │ ├── Plugins.meta │ └── Plugins │ │ ├── Android.meta │ │ ├── Android │ │ ├── AndroidManifest.xml │ │ ├── AndroidManifest.xml.meta │ │ ├── OpenIAB-plugin.jar │ │ └── in-app-purchasing-2.0.1.jar │ │ ├── OpenIAB.meta │ │ ├── OpenIAB │ │ ├── Android.meta │ │ ├── Android │ │ │ ├── OpenIAB_Android.cs │ │ │ └── OpenIAB_Android.cs.meta │ │ ├── IOpenIAB.cs │ │ ├── IOpenIAB.cs.meta │ │ ├── Inventory.cs │ │ ├── Inventory.cs.meta │ │ ├── JSON.cs │ │ ├── JSON.cs.meta │ │ ├── OpenIAB.cs │ │ ├── OpenIAB.cs.meta │ │ ├── OpenIABEventManager.cs │ │ ├── OpenIABEventManager.cs.meta │ │ ├── Options.cs │ │ ├── Options.cs.meta │ │ ├── OptionsVerifyMode.cs │ │ ├── OptionsVerifyMode.cs.meta │ │ ├── Prefabs.meta │ │ ├── Prefabs │ │ │ ├── OpenIABEventManager.prefab │ │ │ └── OpenIABEventManager.prefab.meta │ │ ├── Purchase.cs │ │ ├── Purchase.cs.meta │ │ ├── SearchStrategy.cs │ │ ├── SkuDetails.cs │ │ ├── SkuDetails.cs.meta │ │ ├── WP8.meta │ │ ├── WP8 │ │ │ ├── OpenIAB_WP8.cs │ │ │ └── OpenIAB_WP8.cs.meta │ │ ├── iOS.meta │ │ └── iOS │ │ │ ├── OpenIAB_iOS.cs │ │ │ └── OpenIAB_iOS.cs.meta │ │ ├── OpenIAB_W8Plugin.dll │ │ ├── OpenIAB_W8Plugin.dll.meta │ │ ├── OpenIAB_W8Plugin.pdb │ │ ├── OpenIAB_W8Plugin.pdb.meta │ │ ├── OpenIAB_manual.pdf │ │ ├── WP8.meta │ │ ├── WP8 │ │ ├── OpenIAB_W8Plugin.dll │ │ ├── OpenIAB_W8Plugin.dll.meta │ │ ├── OpenIAB_W8Plugin.pdb │ │ └── OpenIAB_W8Plugin.pdb.meta │ │ ├── iOS.meta │ │ └── iOS │ │ ├── AppStoreBridge.mm │ │ ├── AppStoreBridge.mm.meta │ │ ├── AppStoreDelegate.h │ │ ├── AppStoreDelegate.h.meta │ │ ├── AppStoreDelegate.mm │ │ └── AppStoreDelegate.mm.meta └── unity_src.userprefs └── wp8_dll_src ├── EditorDLL ├── EditorDLL.csproj ├── ProductListing.cs ├── Properties │ └── AssemblyInfo.cs └── Store.cs ├── RealDLL ├── HResult.cs ├── ProductListing.cs ├── Properties │ └── AssemblyInfo.cs ├── RealDLL.csproj └── Store.cs └── UnityW8Plugin.sln /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.obj 51 | *.pch 52 | #*.pdb 53 | *.pgc 54 | *.pgd 55 | *.rsp 56 | *.sbr 57 | *.tlb 58 | *.tli 59 | *.tlh 60 | *.vspscc 61 | .builds 62 | *.dotCover 63 | 64 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 65 | #packages/ 66 | 67 | # Visual C++ cache files 68 | ipch/ 69 | *.aps 70 | *.ncb 71 | *.opensdf 72 | *.sdf 73 | 74 | # Visual Studio profiler 75 | *.psess 76 | *.vsp 77 | 78 | # ReSharper is a .NET coding add-in 79 | _ReSharper* 80 | 81 | # Installshield output folder 82 | [Ee]xpress 83 | 84 | # DocProject is a documentation generator add-in 85 | DocProject/buildhelp/ 86 | DocProject/Help/*.HxT 87 | DocProject/Help/*.HxC 88 | DocProject/Help/*.hhc 89 | DocProject/Help/*.hhk 90 | DocProject/Help/*.hhp 91 | DocProject/Help/Html2 92 | DocProject/Help/html 93 | 94 | # Click-Once directory 95 | publish 96 | 97 | # Others 98 | [Bb]in 99 | [Oo]bj 100 | sql 101 | TestResults 102 | *.Cache 103 | ClientBin 104 | stylecop.* 105 | ~$* 106 | *.dbmdl 107 | Generated_Code #added for RIA/Silverlight projects 108 | 109 | # Backup & report files from converting an old project file to a newer 110 | # Visual Studio version. Backup files are not needed, because we have git ;-) 111 | _UpgradeReport_Files/ 112 | Backup*/ 113 | UpgradeLog*.XML 114 | 115 | 116 | 117 | ############ 118 | ## Windows 119 | ############ 120 | 121 | # Windows image file caches 122 | Thumbs.db 123 | 124 | # Folder config file 125 | Desktop.ini 126 | 127 | 128 | ############# 129 | ## Python 130 | ############# 131 | 132 | *.py[co] 133 | 134 | # Packages 135 | *.egg 136 | *.egg-info 137 | dist 138 | build 139 | eggs 140 | parts 141 | bin 142 | var 143 | sdist 144 | develop-eggs 145 | .installed.cfg 146 | 147 | # Installer logs 148 | pip-log.txt 149 | 150 | # Unit test / coverage reports 151 | .coverage 152 | .tox 153 | 154 | #Translations 155 | *.mo 156 | 157 | #Mr Developer 158 | .mr.developer.cfg 159 | 160 | #OSx 161 | .DS_Store 162 | 163 | # Android Studio (InteliJ) 164 | .idea/ 165 | /.idea/workspace.xml 166 | *.iml 167 | *.iws 168 | *.ipr 169 | /*/out 170 | /*/build 171 | /*/*/production 172 | 173 | #Gradle 174 | .gradletasknamecache 175 | .gradle/ 176 | build/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sample"] 2 | path = sample 3 | url=../OpenIAB-sample-game.git 4 | [submodule "OpenIAB"] 5 | path = OpenIAB 6 | url = ../OpenIAB.git 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. -------------------------------------------------------------------------------- /OpenIAB-Unity-Plugin.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /OpenIAB_manual.odt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/OpenIAB_manual.odt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Dear friends 2 | ------------- 3 | 4 | Currently our small team doesn't have enough time to support and develop the project. I hope in the nearest future we will continue the work. 5 | Thank you! 6 | 7 | 8 | OpenIAB Plugin. Open In-App Billing for Android, iOS and Windows Phone 8 9 | ==================== 10 | 11 | ##Releases 12 | The latest build is always available [here] (https://github.com/onepf/OpenIAB/releases). 13 | 14 | ##About 15 | Supporting in-app purchases for different platforms and stores is not a simple process. The developer has to study new API for each new store that he/she wants to use in an application.

16 | OpenIAB plugin enables Unity developers to reduce integration and maintenance time. The plugin uses one common interface for 3 mobile platforms: Android, iOS and Windows Phone 8. It’s based on [OpenIAB library](https://github.com/onepf/OpenIAB "OpenIAB") developed by One Platform Foundation team.

17 | OpenIAB plugin comes with full source code under Apache 2.0 license.

18 | Supported Stores:
19 | **Android:**
20 | - [Google Play](https://play.google.com/store "Google Play")
21 | - [Amazon Appstore](http://www.amazon.com/mobile-apps/b?node=2350149011 "Amazon Appstore")
22 | - [Yandex.Store](http://store.yandex.com/ "Yandex.Store")
23 | - [Samsung Apps](http://apps.samsung.com/earth/main/getMain.as?COUNTRY_CODE=BLR "Samsung Apps")
24 | - [Nokia Store](http://developer.nokia.com/nokia-x/publish-your-app "Nokia Store")
25 | - [SlideMe](http://slideme.org/ "SlideMe")
26 | - [Appland](http://www.applandinc.com/app-store/ "Appland")
27 | - [Aptoide](http://m.aptoide.com/ "Aptoide")
28 | - [AppMall](http://www.openmobileww.com/#!appmall/cunq "AppMall")
29 | 30 | **iOS:** [Apple Store](https://itunes.apple.com/en/genre/mobile-software-applications/id36?mt=8 "Apple Store") 31 | 32 | **Windows phone 8:** [Windows Phone Store](http://www.windowsphone.com/en-us/store "Windows Phone Store") 33 | 34 | ##Version 35 | The current version is 0.9.8.6. 36 | 37 | ##Tutorial 38 | For a comprehensive tutorial, Check-out the complete turorial on [master](https://github.com/onepf/OpenIAB-Unity-Plugin/blob/master/unity_plugin/unity_src/Assets/Plugins/OpenIAB_manual.pdf?raw=true) here. 39 | 40 | ##Sample project 41 | You can check out this sample project [here](https://github.com/GrimReio/OpenIAB-sample-game). 42 | 43 | ##How to build plugin 44 | Plugin build view [Gradle][2]. You no need to download binary package of gradle tools, only requirements 45 | is installed JDK version 1.6 or great and setup JAVA_HOME environment variable.
46 |
47 | Before build plugin you must:
48 | 1. Install [Unity][1], start it and accept license agreement. 49 | 2. Unity must be closed while build is running. 50 | 51 | For build project you must run from terminal in `unity_plugin` directory of project
52 | ```bash 53 | ../gradlew clean buildPlugin 54 | ``` 55 | On Windows run
56 | ```bash 57 | ..\gradlew.bat clean buildPlugin 58 | ``` 59 | 60 | If build was successfully, you can find output unitypackage file in directory
61 | 62 | `unity_plugin/build/outputs` 63 | 64 | Build tools search unity by default path for OS. If you change default path, you need to set 65 | path `unityExecutable` property in `gradle.properties` file. 66 | 67 | [1]: https://unity3d.com/unity/download 68 | [2]: http://www.gradle.org 69 | 70 | ##Options 71 | Create Options object. 72 | ``` 73 | var options = new Options(); 74 | ``` 75 | 76 | Set store search strategy. 77 | ``` 78 | options.storeSearchStrategy = SearchStrategy.INSTALLER_THEN_BEST_FIT; 79 | ``` 80 | 81 | Set available stores to restrict the set of stores to check. 82 | ``` 83 | options.availableStoreNames = new string[] { OpenIAB_Android.STORE_GOOGLE, OpenIAB_Android.STORE_YANDEX }; 84 | ``` 85 | 86 | Set preferred store names (works only for store search strategy ```OpenIabHelper.Options.SEARCH_STRATEGY_BEST_FIT``` and ```OpenIabHelper.Options.SEARCH_STRATEGY_INSTALLER_THEN_BEST_FIT```). 87 | ``` 88 | options.prefferedStoreNames = new string[] { OpenIAB_Android.STORE_GOOGLE, OpenIAB_Android.STORE_YANDEX }; 89 | ``` 90 | 91 | Set store keys. 92 | ``` 93 | options.storeKeys = new Dictionary { {OpenIAB_Android.STORE_GOOGLE, "publicKey"} }; 94 | ``` 95 | 96 | Set verifying mode (applicable only for Google Play, Appland, Aptoide, AppMall, SlideMe, Yandex.Store). 97 | ``` 98 | options.verifyMode = OptionsVerifyMode.VERIFY_SKIP; 99 | ``` 100 | 101 | Init with specified options. 102 | ``` 103 | OpenIAB.init(options); 104 | ``` 105 | 106 | ##Suggestions/Questions 107 | We seek to constantly improve our project and give Unity developers more power when working with in-app purchases. We are open to any comments and suggestions you may have regarding the additional features to be implemented in our plugin. 108 | 109 | If you know about issues we missed, please let us know in 110 | Issues on GitHub: https://github.com/onepf/OpenIAB/issues
111 | or by email: unitysupport@onepf.org 112 | 113 | If you detect some issues with integration into your project, please let us know in 114 | http://stackoverflow.com/questions/ask/advice? 115 | 116 | ``` 117 | When you post a question on stackoverlow, mark your post with the following tags 118 | “in-app purchase”, “unity3d”, “openiab”. It will help you to get a faster response 119 | from our community. 120 | ``` 121 | 122 | ##License 123 | The source code of the OpenIAB Unity plugin and OpenIAB library are available under the terms of the Apache License, Version 2.0: 124 | http://www.apache.org/licenses/LICENSE-2.0 125 | 126 | The OpenIAB API specification and the related texts are available under the terms of the Creative Commons Attribution 2.5 license: 127 | http://creativecommons.org/licenses/by/2.5/ 128 | 129 | 130 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | task wrapper(type: Wrapper) { 2 | gradleVersion = '1.12' 3 | } 4 | 5 | buildscript { 6 | repositories { 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:2.2.3' 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | // maven { 18 | // url 'https://oss.sonatype.org/content/repositories/snapshots/' 19 | // } 20 | maven { url 'https://raw.githubusercontent.com/onepf/OPF-mvn-repo/master/' } 21 | jcenter() 22 | } 23 | 24 | ext { 25 | compileSdkVersion = 21 26 | buildToolsVersion = "21.1.2" 27 | minSdkVersion = 8 28 | targetSdkVersion = 19 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | #unityExecutable=Path to unity -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Dec 22 12:25:19 EET 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':Unity Plugin', ':library' 2 | project(':Unity Plugin').projectDir = file('unity_plugin') 3 | project(':library').projectDir = new File('OpenIAB/library') -------------------------------------------------------------------------------- /unity_plugin/.gitignore: -------------------------------------------------------------------------------- 1 | *.jar, !/libs/*.jar 2 | *.jar.meta 3 | *.so 4 | *.so.meta -------------------------------------------------------------------------------- /unity_plugin/README.md: -------------------------------------------------------------------------------- 1 | OpenIAB - Unity Plugin 2 | ===== 3 | This library is Java part of our Unity plugin. 4 | 5 | Take a look at our [example project](https://github.com/onepf/OpenIAB-angrybots) based on the Unity **AngryBots** demo. 6 | 7 | Build Package 8 | ===== 9 | Simply run ```ant build``` in the root folder of the repository. Then you can find package in the ```bin``` folder. 10 | We don't use latest APIs, so it should be possible to build this project with any somewhat recent Unity version. 11 | 12 | If you need to set custom Unity location, you can do so in the ```OpenIAB/unity_plugin/ant.properties``` file. e. g. 13 | ```unity.path=C:/Program Files (x86)/Unity/Editor/Unity.exe``` 14 | 15 | 16 | Integration 17 | ===== 18 | Build or download Unity [package](https://github.com/onepf/OpenIAB/releases/) and import it in your project. There is OpenIAB.jar file in the package, which contains compile output of the plugin and of the [OpenIAB](/) library. 19 | If you want to use source code instead of jar, you need to put ``` UnityPlugin.java ``` and ``` UnityProxyActivity.java ``` in the /Assets/Plugins/Android/src/org/onepf/openiab folder. 20 | 21 | There is also ``` AndroidManifest.xml ``` in the /Assets/Plugins/Android. Developer can add project specific settings to it. 22 | 23 | Now you can run demo scene with some test buttons. 24 | 25 | *__Fortumo__ is unavailable in the Asset Store package, but it can be found in the latest version from 'master' branch.* 26 | 27 | 5 Simple Steps 28 | ===== 29 | 1. Place **OpenIABEventManager** prefab on the current scene. 30 | 31 | 32 | 2. Subscribe to the plugin events: 33 | ```c# 34 | private void OnEnable() { 35 | OpenIABEventManager.billingSupportedEvent += billingSupportedEvent; 36 | OpenIABEventManager.billingNotSupportedEvent += billingNotSupportedEvent; 37 | OpenIABEventManager.queryInventorySucceededEvent += queryInventorySucceededEvent; 38 | OpenIABEventManager.queryInventoryFailedEvent += queryInventoryFailedEvent; 39 | OpenIABEventManager.purchaseSucceededEvent += purchaseSucceededEvent; 40 | OpenIABEventManager.purchaseFailedEvent += purchaseFailedEvent; 41 | OpenIABEventManager.consumePurchaseSucceededEvent += consumePurchaseSucceededEvent; 42 | OpenIABEventManager.consumePurchaseFailedEvent += consumePurchaseFailedEvent; 43 | } 44 | ``` 45 | 46 | 3. Map sku's for different stores: 47 | ```c# 48 | private void Start() { 49 | // SKU's for iOS MUST be mapped. Mappings for other stores are optional 50 | OpenIAB.mapSku(SKU, OpenIAB_iOS.STORE, "some.ios.sku"); 51 | 52 | OpenIAB.mapSku(SKU, OpenIAB.STORE_GOOGLE, "google-play.sku"); 53 | OpenIAB.mapSku(SKU, STORE_CUSTOM, "onepf.sku"); 54 | } 55 | ``` 56 | 57 | 4. Call ``` init ``` method passing it preferred stores list with public keys, in order to start billing service. 58 | ```c# 59 | OpenIAB.init(new Dictionary { 60 | {OpenIAB_Android.STORE_GOOGLE, "google_public_key"}, 61 | {OpenIAB_Android.STORE_APPLAND, "appland_public_key"}, 62 | {OpenIAB_Android.STORE_YANDEX, "yandexpublic_key"} 63 | }); 64 | ``` 65 | 66 | 5. Use provided API to query inventory, make purchases, etc. 67 | ```c# 68 | OpenIAB.queryInventory(); 69 | 70 | OpenIAB.purchaseProduct("s.k.u"); 71 | 72 | OpenIAB.unbindService(); 73 | ``` 74 | 75 | Here is example of the purchase event handling from our demo project: 76 | 77 | ```c# 78 | private const string SKU_MEDKIT = "sku_medkit"; 79 | private const string SKU_AMMO = "sku_ammo"; 80 | private const string SKU_INFINITE_AMMO = "sku_infinite_ammo"; 81 | private const string SKU_COWBOY_HAT = "sku_cowboy_hat"; 82 | 83 | // Some game logic refs 84 | [SerializeField] 85 | private AmmoBox _playerAmmoBox = null; 86 | [SerializeField] 87 | private MedKitPack _playerMedKitPack = null; 88 | [SerializeField] 89 | private PlayerHat _playerHat = null; 90 | 91 | private void OnPurchaseSucceded(Purchase purchase) { 92 | // Optional verification of the payload. Can be moved to a custom server 93 | if (!VerifyDeveloperPayload(purchase.DeveloperPayload)) { 94 | return; 95 | } 96 | switch (purchase.Sku) { 97 | case SKU_MEDKIT: 98 | OpenIAB.consumeProduct(purchase); 99 | return; 100 | case SKU_AMMO: 101 | OpenIAB.consumeProduct(purchase); 102 | return; 103 | case SKU_COWBOY_HAT: 104 | _playerHat.PutOn = true; 105 | break; 106 | case SKU_INFINITE_AMMO: 107 | _playerAmmoBox.IsInfinite = true; 108 | break; 109 | default: 110 | Debug.LogWarning("Unknown SKU: " + purchase.Sku); 111 | break; 112 | } 113 | } 114 | ``` 115 | 116 | 117 | API 118 | ===== 119 | All work is done through the two classes: ``` OpenIAB ```, ``` OpenIABEventManager ```. 120 | 121 | Full list of the provided events: 122 | 123 | ```c# 124 | // Fired after init is called when billing is supported on the device 125 | public static event Action billingSupportedEvent; 126 | 127 | // Fired after init is called when billing is not supported on the device 128 | public static event Action billingNotSupportedEvent; 129 | 130 | // Fired when the inventory and purchase history query has returned 131 | public static event Action queryInventorySucceededEvent; 132 | 133 | // Fired when the inventory and purchase history query fails 134 | public static event Action queryInventoryFailedEvent; 135 | 136 | // Fired when a purchase of a product or a subscription succeeds 137 | public static event Action purchaseSucceededEvent; 138 | 139 | // Fired when a purchase fails 140 | public static event Action purchaseFailedEvent; 141 | 142 | // Fired when a call to consume a product succeeds 143 | public static event Action consumePurchaseSucceededEvent; 144 | 145 | // Fired when a call to consume a product fails 146 | public static event Action consumePurchaseFailedEvent; 147 | 148 | // Fired when transaction was restored. iOS only 149 | public static event Action transactionRestoredEvent; 150 | 151 | // Fired when transaction restoration process failed. iOS only 152 | public static event Action restoreFailedEvent; 153 | 154 | // Fired when transaction restoration process succeeded. iOS only 155 | public static event Action restoreSucceededEvent; 156 | ``` 157 | 158 | Full list of the provided methods: 159 | 160 | ```c# 161 | // Starts up the billing service. This will also check to see if in app billing is supported and fire the appropriate event 162 | public static void init(Dictionary storeKeys); 163 | 164 | // Maps sku for the supported stores 165 | public static void mapSku(string sku, string storeName, string storeSku); 166 | 167 | // Unbinds and shuts down the billing service 168 | public static void unbindService(); 169 | 170 | // Returns whether subscriptions are supported on the current device 171 | public static bool areSubscriptionsSupported(); 172 | 173 | // Sends a request to get all completed purchases and product information 174 | public static void queryInventory(); 175 | 176 | // Purchases the product with the given sku and developerPayload 177 | public static void purchaseProduct(string sku, string developerPayload=""); 178 | 179 | // Purchases the subscription with the given sku and developerPayload 180 | public static void purchaseSubscription(string sku, string developerPayload=""); 181 | 182 | // Sends out a request to consume the product 183 | public static void consumeProduct(Purchase purchase); 184 | 185 | // Restores purchases. Needed only for iOS store 186 | public static void restoreTransactions(); 187 | ``` 188 | 189 | Android 190 | ===== 191 | OpenIAB uses proxy activity instead of inheriting Unity activity to simplify integration with other plugins. 192 | If you already have ```AndroidManifest.xml``` in your project, simply add there our permissions, receiver and activity declaration. 193 | 194 | ``` 195 | 196 | 197 | ... 198 | 199 | 203 | 204 | 205 | 206 | 207 | 210 | 211 | 212 | 213 | 214 | 215 | ... 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | ... 228 | 229 | 230 | ``` 231 | 232 | 233 | Advanced 234 | ===== 235 | You can reuse existing API and add support to a new platform by implementing ```IOpenIAB``` interface. 236 | Then you can create instance of your class in the ```OpenIAB```. 237 | ```c# 238 | static OpenIAB() { 239 | #if UNITY_ANDROID 240 | _billing = new OpenIAB_Android(); 241 | #elif UNITY_IOS 242 | _billing = new OpenIAB_iOS(); 243 | #else 244 | _billing = new OpenIAB_custom(); 245 | #endif 246 | } 247 | 248 | Test keystore and key password: openiab 249 | -------------------------------------------------------------------------------- /unity_plugin/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | def sep = File.separator 4 | def projectDir = rootProject.projectDir.absolutePath; 5 | def unityRootAbsolutePath = "${projectDir}${sep}unity_plugin${sep}unity_src" 6 | def unitySrcPath = "${unityRootAbsolutePath}${sep}Assets${sep}Plugins${sep}Android" 7 | def outAbsoluteDir = "${project.buildDir.absolutePath}${sep}intermediates${sep}unityPlugin${sep}classes" 8 | def outJarAbsoluteDir = "${project.buildDir.absolutePath}${sep}intermediates${sep}unityPlugin" 9 | def unityPackageAbsolutePath = "${project.buildDir.absolutePath}${sep}outputs" 10 | def openIabVersion = '0.9.7.2' 11 | 12 | android { 13 | compileSdkVersion rootProject.ext.compileSdkVersion 14 | buildToolsVersion rootProject.ext.buildToolsVersion 15 | 16 | defaultConfig { 17 | minSdkVersion 8 18 | targetSdkVersion 19 19 | versionCode 1 20 | versionName "1.0" 21 | 22 | applicationId 'org.onepf.openiab' 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: '*.jar') 28 | compile project(':library') 29 | compile 'com.amazon:in-app-purchasing:2.0.0' 30 | compile 'com.braintree:fortumo-in-app:9.1.2' 31 | } 32 | 33 | task buildPlugin(dependsOn: 'assembleRelease') << { 34 | final def unityPath = getUnityExecutablePath() 35 | delete fileTree(dir: unityPackageAbsolutePath , include: '*.unitypackage') 36 | delete fileTree(dir: outAbsoluteDir, include: "*") 37 | mkdir outAbsoluteDir 38 | mkdir unityPackageAbsolutePath 39 | 40 | //def openIabJar = project.configurations.compile.find { 41 | // it.name.startsWith "openiab-${openIabVersion}" 42 | //} 43 | 44 | def openIabJar = project.rootProject.file('OpenIAB/library/build/intermediates/bundles/release/classes.jar') 45 | 46 | //assert openIabJar != null 47 | ant.unzip(src: openIabJar.absolutePath, dest: outAbsoluteDir) 48 | 49 | // Copy compiled unity-plugin java source 50 | copy { 51 | from "${project(':Unity Plugin').projectDir.absolutePath}" + "${sep}build${sep}intermediates${sep}classes${sep}release" 52 | into outAbsoluteDir 53 | include '**/*.class' 54 | } 55 | 56 | project.exec { 57 | commandLine 'jar' 58 | args 'cf' 59 | args "${outJarAbsoluteDir}${sep}OpenIAB-plugin.jar" 60 | args '-C' 61 | args outAbsoluteDir 62 | args '.' 63 | } 64 | 65 | copy { 66 | from outJarAbsoluteDir 67 | include 'OpenIAB-plugin.jar' 68 | into unitySrcPath 69 | } 70 | 71 | println "Unity executable: $unityPath" 72 | println "Unity package source root: $unityRootAbsolutePath" 73 | println "Unity package build: $unityPackageAbsolutePath" 74 | 75 | project.exec { 76 | commandLine unityPath 77 | args '-batchMode' 78 | args '-projectPath' 79 | args "${unityRootAbsolutePath}" 80 | args '-exportPackage' 81 | args "Assets${sep}OpenIAB-demo" 82 | args "Assets${sep}Plugins" 83 | args "${unityPackageAbsolutePath}${sep}OpenIAB-plugin.unitypackage" 84 | args '-quit' 85 | } 86 | } 87 | 88 | def getUnityExecutablePath() { 89 | if (project.hasProperty('unityExecutable')) { 90 | return project.property('unityExecutable'); 91 | } else { 92 | def paths = ['unityMacPath', 'unityWin86Path', 'unityWin64Path',] 93 | for (path in paths) { 94 | if (file(project.property(path)).exists()) { 95 | return project.property(path); 96 | } 97 | } 98 | } 99 | 100 | throw new RuntimeException("Unity not found. Please make sure Unity " + 101 | "is installed at default location or provide 'unityExecutable' property."); 102 | } 103 | -------------------------------------------------------------------------------- /unity_plugin/gradle.properties: -------------------------------------------------------------------------------- 1 | unityMacPath = /Applications/Unity/Unity.app/Contents/MacOS/Unity 2 | unityWin86Path = C:\\Program Files\\Unity\\Editor\\Unity.exe 3 | unityWin64Path = C:\\Program Files (x86)\\Unity\\Editor\\Unity.exe -------------------------------------------------------------------------------- /unity_plugin/libs/classes.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/libs/classes.jar -------------------------------------------------------------------------------- /unity_plugin/libs/in-app-purchasing-2.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/libs/in-app-purchasing-2.0.0.jar -------------------------------------------------------------------------------- /unity_plugin/openiab-unity-test.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/openiab-unity-test.keystore -------------------------------------------------------------------------------- /unity_plugin/openiab.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/openiab.keystore -------------------------------------------------------------------------------- /unity_plugin/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | android.library=true 14 | # Project target. 15 | target=android-15 16 | android.library.reference.1=../library 17 | -------------------------------------------------------------------------------- /unity_plugin/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /unity_plugin/src/main/java/org/onepf/openiab/UnityProxyActivity.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | package org.onepf.openiab; 18 | 19 | import android.app.Activity; 20 | import android.content.BroadcastReceiver; 21 | import android.content.Context; 22 | import android.content.Intent; 23 | import android.content.IntentFilter; 24 | import android.os.Bundle; 25 | import android.util.Log; 26 | import org.onepf.oms.appstore.googleUtils.IabHelper; 27 | import org.onepf.oms.appstore.googleUtils.IabResult; 28 | 29 | /** 30 | * Proxy activity is required to avoid making changes in the main Unity activity 31 | * It is created when purchase is started 32 | */ 33 | public class UnityProxyActivity extends Activity { 34 | static final String ACTION_FINISH = "org.onepf.openiab.ACTION_FINISH"; 35 | private BroadcastReceiver broadcastReceiver; 36 | 37 | @Override 38 | public void onCreate(Bundle savedInstanceState) { 39 | super.onCreate(savedInstanceState); 40 | 41 | broadcastReceiver = new BroadcastReceiver() { 42 | @Override 43 | public void onReceive(Context context, Intent intent) { 44 | Log.d(UnityPlugin.TAG, "Finish broadcast was received"); 45 | if (!UnityProxyActivity.this.isFinishing()) { 46 | finish(); 47 | } 48 | } 49 | }; 50 | registerReceiver(broadcastReceiver, new IntentFilter(ACTION_FINISH)); 51 | 52 | if (UnityPlugin.sendRequest) { 53 | UnityPlugin.sendRequest = false; 54 | 55 | Intent i = getIntent(); 56 | String sku = i.getStringExtra("sku"); 57 | String developerPayload = i.getStringExtra("developerPayload"); 58 | boolean inapp = i.getBooleanExtra("inapp", true); 59 | 60 | try { 61 | if (inapp) { 62 | UnityPlugin.instance().getHelper().launchPurchaseFlow(this, sku, UnityPlugin.RC_REQUEST, UnityPlugin.instance().getPurchaseFinishedListener(), developerPayload); 63 | } else { 64 | UnityPlugin.instance().getHelper().launchSubscriptionPurchaseFlow(this, sku, UnityPlugin.RC_REQUEST, UnityPlugin.instance().getPurchaseFinishedListener(), developerPayload); 65 | } 66 | } catch (java.lang.IllegalStateException e) { 67 | UnityPlugin.instance().getPurchaseFinishedListener().onIabPurchaseFinished(new IabResult(IabHelper.BILLING_RESPONSE_RESULT_BILLING_UNAVAILABLE, "Cannot start purchase process. Billing unavailable."), null); 68 | } 69 | } 70 | } 71 | 72 | @Override 73 | protected void onDestroy() { 74 | super.onDestroy(); 75 | unregisterReceiver(broadcastReceiver); 76 | } 77 | 78 | @Override 79 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 80 | Log.d(UnityPlugin.TAG, "onActivityResult(" + requestCode + ", " + resultCode + ", " + data); 81 | 82 | // Pass on the activity result to the helper for handling 83 | if (!UnityPlugin.instance().getHelper().handleActivityResult(requestCode, resultCode, data)) { 84 | // not handled, so handle it ourselves (here's where you'd 85 | // perform any handling of activity results not related to in-app 86 | // billing... 87 | super.onActivityResult(requestCode, resultCode, data); 88 | } else { 89 | Log.d(UnityPlugin.TAG, "onActivityResult handled by IABUtil."); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /unity_plugin/src/main/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /unity_plugin/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ACTIVITY_ENTRY_NAME 4 | 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/.gitignore: -------------------------------------------------------------------------------- 1 | /Library/ 2 | /Temp/ 3 | /ProjectSettings/ 4 | *.csproj 5 | *.sln 6 | /Export/ 7 | *.unity_src.sln.DotSettings 8 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/.gitignore: -------------------------------------------------------------------------------- 1 | /UnityVS/ 2 | *.meta 3 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d423939e2bdd34499b5dd6cbb5cce81 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 47c3c77b488bde14eac761a5144660ed 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/AssetStoreTools.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/AssetStoreTools/Editor/AssetStoreTools.dll -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/AssetStoreTools.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 11188de2b6632fa4486c470af4b55fa0 3 | MonoAssemblyImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | userData: 8 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/AssetStoreToolsExtra.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e35231d99115e9e4c8cb29414445831f 3 | PluginImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | isPreloaded: 0 8 | platformData: 9 | Any: 10 | enabled: 0 11 | settings: {} 12 | Editor: 13 | enabled: 1 14 | settings: 15 | DefaultValueInitialized: true 16 | WindowsStoreApps: 17 | enabled: 0 18 | settings: 19 | CPU: AnyCPU 20 | userData: 21 | assetBundleName: 22 | assetBundleVariant: 23 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/DroidSansMono.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/AssetStoreTools/Editor/DroidSansMono.ttf -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/DroidSansMono.ttf.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 35021dda9bd03434195c7dcd6ad7618f 3 | TrueTypeFontImporter: 4 | serializedVersion: 2 5 | fontSize: 16 6 | fontColor: {r: 1, g: 1, b: 1, a: 1} 7 | forceTextureCase: -2 8 | characterSpacing: 1 9 | characterPadding: 0 10 | includeFontData: 1 11 | use2xBehaviour: 0 12 | fontNames: [] 13 | customCharacters: 14 | fontRenderingMode: 0 15 | userData: 16 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/AssetStoreTools/Editor/icon.png -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Editor/icon.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 41844c716792706449720732c95b2747 3 | TextureImporter: 4 | serializedVersion: 2 5 | mipmaps: 6 | mipMapMode: 0 7 | enableMipMap: 1 8 | linearTexture: 0 9 | correctGamma: 0 10 | fadeOut: 0 11 | borderMipMap: 0 12 | mipMapFadeDistanceStart: 1 13 | mipMapFadeDistanceEnd: 3 14 | bumpmap: 15 | convertToNormalMap: 0 16 | externalNormalMap: 0 17 | heightScale: .25 18 | normalMapFilter: 0 19 | isReadable: 0 20 | grayScaleToAlpha: 0 21 | generateCubemap: 0 22 | seamlessCubemap: 0 23 | textureFormat: -1 24 | maxTextureSize: 1024 25 | textureSettings: 26 | filterMode: -1 27 | aniso: -1 28 | mipBias: -1 29 | wrapMode: -1 30 | nPOTScale: 1 31 | lightmap: 0 32 | compressionQuality: 50 33 | textureType: -1 34 | buildTargetSettings: [] 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Labels.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/AssetStoreTools/Labels.asset -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/AssetStoreTools/Labels.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e069f1737d01e4f4f96176d31960efc7 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/OpenIAB-demo.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c304271f3386b7a41acacc074c6db74b 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/OpenIAB-demo/OpenIAB-demo.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/OpenIAB-demo/OpenIAB-demo.unity -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/OpenIAB-demo/OpenIAB-demo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcedacdf4c2d41647a681ec826226987 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/OpenIAB-demo/OpenIABTest.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using OnePF; 19 | using System.Collections.Generic; 20 | 21 | /** 22 | * Example of OpenIAB usage 23 | */ 24 | public class OpenIABTest : MonoBehaviour 25 | { 26 | const string SKU = "sku"; 27 | #pragma warning disable 0414 28 | string _label = ""; 29 | #pragma warning restore 0414 30 | bool _isInitialized = false; 31 | Inventory _inventory = null; 32 | 33 | private void OnEnable() 34 | { 35 | // Listen to all events for illustration purposes 36 | OpenIABEventManager.billingSupportedEvent += billingSupportedEvent; 37 | OpenIABEventManager.billingNotSupportedEvent += billingNotSupportedEvent; 38 | OpenIABEventManager.queryInventorySucceededEvent += queryInventorySucceededEvent; 39 | OpenIABEventManager.queryInventoryFailedEvent += queryInventoryFailedEvent; 40 | OpenIABEventManager.purchaseSucceededEvent += purchaseSucceededEvent; 41 | OpenIABEventManager.purchaseFailedEvent += purchaseFailedEvent; 42 | OpenIABEventManager.consumePurchaseSucceededEvent += consumePurchaseSucceededEvent; 43 | OpenIABEventManager.consumePurchaseFailedEvent += consumePurchaseFailedEvent; 44 | } 45 | private void OnDisable() 46 | { 47 | // Remove all event handlers 48 | OpenIABEventManager.billingSupportedEvent -= billingSupportedEvent; 49 | OpenIABEventManager.billingNotSupportedEvent -= billingNotSupportedEvent; 50 | OpenIABEventManager.queryInventorySucceededEvent -= queryInventorySucceededEvent; 51 | OpenIABEventManager.queryInventoryFailedEvent -= queryInventoryFailedEvent; 52 | OpenIABEventManager.purchaseSucceededEvent -= purchaseSucceededEvent; 53 | OpenIABEventManager.purchaseFailedEvent -= purchaseFailedEvent; 54 | OpenIABEventManager.consumePurchaseSucceededEvent -= consumePurchaseSucceededEvent; 55 | OpenIABEventManager.consumePurchaseFailedEvent -= consumePurchaseFailedEvent; 56 | } 57 | 58 | private void Start() 59 | { 60 | // Map skus for different stores 61 | OpenIAB.mapSku(SKU, OpenIAB_Android.STORE_GOOGLE, "sku"); 62 | OpenIAB.mapSku(SKU, OpenIAB_Android.STORE_AMAZON, "sku"); 63 | OpenIAB.mapSku(SKU, OpenIAB_Android.STORE_SAMSUNG, "100000105017/samsung_sku"); 64 | OpenIAB.mapSku(SKU, OpenIAB_iOS.STORE, "sku"); 65 | OpenIAB.mapSku(SKU, OpenIAB_WP8.STORE, "ammo"); 66 | } 67 | 68 | const float X_OFFSET = 10.0f; 69 | const float Y_OFFSET = 10.0f; 70 | const int SMALL_SCREEN_SIZE = 800; 71 | const int LARGE_FONT_SIZE = 34; 72 | const int SMALL_FONT_SIZE = 24; 73 | const int LARGE_WIDTH = 380; 74 | const int SMALL_WIDTH = 160; 75 | const int LARGE_HEIGHT = 100; 76 | const int SMALL_HEIGHT = 40; 77 | 78 | int _column = 0; 79 | int _row = 0; 80 | 81 | private bool Button(string text) 82 | { 83 | float width = Screen.width / 2.0f - X_OFFSET * 2; 84 | float height = (Screen.width >= SMALL_SCREEN_SIZE || Screen.height >= SMALL_SCREEN_SIZE) ? LARGE_HEIGHT : SMALL_HEIGHT; 85 | 86 | bool click = GUI.Button(new Rect( 87 | X_OFFSET + _column * X_OFFSET * 2 + _column * width, 88 | Y_OFFSET + _row * Y_OFFSET + _row * height, 89 | width, height), 90 | text); 91 | 92 | ++_column; 93 | if (_column > 1) 94 | { 95 | _column = 0; 96 | ++_row; 97 | } 98 | 99 | return click; 100 | } 101 | 102 | private void OnGUI() 103 | { 104 | _column = 0; 105 | _row = 0; 106 | 107 | GUI.skin.button.fontSize = (Screen.width >= SMALL_SCREEN_SIZE || Screen.height >= SMALL_SCREEN_SIZE) ? LARGE_FONT_SIZE : SMALL_FONT_SIZE; 108 | 109 | if (Button("Initialize OpenIAB")) 110 | { 111 | // Application public key 112 | var googlePublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgEEaiFfxugLWAH4CQqXYttXlj3GI2ozlcnWlZDaO2VYkcUhbrAz368FMmw2g40zgIDfyopFqETXf0dMTDw7VH3JOXZID2ATtTfBXaU4hqTf2lSwcY9RXe/Uz0x1nf1oLAf85oWZ7uuXScR747ekzRZB4vb4afm2DsbE30ohZD/WzQ22xByX6583yYE19RdE9yJzFckEPlHuOeMgKOa4WErt11PHB6FTdT5eN96/jjjeEoYhX/NGkOWKW0Y0T0A7CdUC0D4t2xxkzAQHdgLfcRw9+/EIcaysLhncWYiCifJrRBGpqZU1IrNuehrC5FXUN99786c/TwlxNG5nflE6sWwIDAQAB"; 113 | var yandexPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApvU8l4ONEEsSGznPN6DnjIbJnv6vEgm08nbbi+2fMc0V46N7x7jBWTWAf2K6XLZg/rLUkqbWISq12PLvt7ydcsD+Hb9ZubdN2h8LNCTohVPeDbJjd5khtF4J5FNP2/XSTc1C7cSCBTGmqH0fUr77v4x/JMpxKlSjPN6KbNnaF2BLDAdi3012lz2XX4BVgUj7LArID/vYSYGlwMzMkvhUSpvZOM/WIPN+8YDgQAFBlRGRjLhY/3Vpq/AtXtVAzzyfTOZYkwNqdXpwAq5+/51LphowUI5NEBYh8lhQeOJmPNA6EcF1h5L9cJTVLy3bkuCXcjoN2eEO1Nq0h/40G0R4pwIDAQAB"; 114 | var slideMePublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAogOQb0mMbuq4FQ4ZhWRhN8k76/gXOUE370VubZa9Up25GdptYXoRNniecUTDLyjfvWp7+YFW8iPqIp523qNXtQ0EynNhK4xNLvJCd1CjfAju6M0f+o8MOL1zV7g3dHqxICZoHwqBbQOWneDzG/DzJ22AVdLKwty0qbv8ESaCOCJe31ZnoYVMw5KNVkSuRrrhiGGh6xj7F3qZ0T5TOSp3fK7soDamQLevuU7Ndn5IQACjo92HNN0O2PR2cvEjkCRuIkNk2hnqinac984JCzCC0SC/JBnUZUAeYJ7Y8sjT+79z1T1g7yGgDesopnqORiBkeXEZHrFy7PifdA/ZX7rRwQIDAQAB"; 115 | 116 | var options = new Options(); 117 | options.checkInventoryTimeoutMs = Options.INVENTORY_CHECK_TIMEOUT_MS * 2; 118 | options.discoveryTimeoutMs = Options.DISCOVER_TIMEOUT_MS * 2; 119 | options.checkInventory = false; 120 | options.verifyMode = OptionsVerifyMode.VERIFY_SKIP; 121 | options.prefferedStoreNames = new string[] { OpenIAB_Android.STORE_AMAZON }; 122 | options.availableStoreNames = new string[] { OpenIAB_Android.STORE_AMAZON }; 123 | options.storeKeys = new Dictionary { {OpenIAB_Android.STORE_GOOGLE, googlePublicKey} }; 124 | options.storeKeys = new Dictionary { { OpenIAB_Android.STORE_YANDEX, yandexPublicKey } }; 125 | options.storeKeys = new Dictionary { { OpenIAB_Android.STORE_SLIDEME, slideMePublicKey } }; 126 | options.storeSearchStrategy = SearchStrategy.INSTALLER_THEN_BEST_FIT; 127 | 128 | // Transmit options and start the service 129 | OpenIAB.init(options); 130 | } 131 | 132 | if (!_isInitialized) 133 | return; 134 | 135 | if (Button("Query Inventory")) 136 | { 137 | OpenIAB.queryInventory(new string[] { SKU }); 138 | } 139 | 140 | if (Button("Purchase Product")) 141 | { 142 | OpenIAB.purchaseProduct(SKU); 143 | } 144 | 145 | if (Button("Consume Product")) 146 | { 147 | if (_inventory != null && _inventory.HasPurchase(SKU)) 148 | OpenIAB.consumeProduct(_inventory.GetPurchase(SKU)); 149 | } 150 | 151 | // Android specific buttons 152 | #if UNITY_ANDROID 153 | if (Button("Test Purchase")) 154 | { 155 | OpenIAB.purchaseProduct("android.test.purchased"); 156 | } 157 | 158 | if (Button("Test Consume")) 159 | { 160 | if (_inventory != null && _inventory.HasPurchase("android.test.purchased")) 161 | OpenIAB.consumeProduct(_inventory.GetPurchase("android.test.purchased")); 162 | } 163 | 164 | if (Button("Test Item Unavailable")) 165 | { 166 | OpenIAB.purchaseProduct("android.test.item_unavailable"); 167 | } 168 | 169 | if (Button("Test Purchase Canceled")) 170 | { 171 | OpenIAB.purchaseProduct("android.test.canceled"); 172 | } 173 | #endif 174 | } 175 | 176 | private void billingSupportedEvent() 177 | { 178 | _isInitialized = true; 179 | Debug.Log("billingSupportedEvent"); 180 | } 181 | private void billingNotSupportedEvent(string error) 182 | { 183 | Debug.Log("billingNotSupportedEvent: " + error); 184 | } 185 | private void queryInventorySucceededEvent(Inventory inventory) 186 | { 187 | Debug.Log("queryInventorySucceededEvent: " + inventory); 188 | if (inventory != null) 189 | { 190 | _label = inventory.ToString(); 191 | _inventory = inventory; 192 | } 193 | } 194 | private void queryInventoryFailedEvent(string error) 195 | { 196 | Debug.Log("queryInventoryFailedEvent: " + error); 197 | _label = error; 198 | } 199 | private void purchaseSucceededEvent(Purchase purchase) 200 | { 201 | Debug.Log("purchaseSucceededEvent: " + purchase); 202 | _label = "PURCHASED:" + purchase.ToString(); 203 | } 204 | private void purchaseFailedEvent(int errorCode, string errorMessage) 205 | { 206 | Debug.Log("purchaseFailedEvent: " + errorMessage); 207 | _label = "Purchase Failed: " + errorMessage; 208 | } 209 | private void consumePurchaseSucceededEvent(Purchase purchase) 210 | { 211 | Debug.Log("consumePurchaseSucceededEvent: " + purchase); 212 | _label = "CONSUMED: " + purchase.ToString(); 213 | } 214 | private void consumePurchaseFailedEvent(string error) 215 | { 216 | Debug.Log("consumePurchaseFailedEvent: " + error); 217 | _label = "Consume Failed: " + error; 218 | } 219 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/OpenIAB-demo/OpenIABTest.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ee45b370a2ff9294ca38c4adab3c7f61 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 54bdf4a6335d75b4e95dd916ee711965 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/Android.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2f812238581f6544ea81e5c1ea5eb326 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/Android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 18 | 22 | 23 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/Android/AndroidManifest.xml.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5d6b0e0686f7dca429ffe478808df92c 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/Android/OpenIAB-plugin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/Android/OpenIAB-plugin.jar -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/Android/in-app-purchasing-2.0.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/Android/in-app-purchasing-2.0.1.jar -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 914bdc6bbb7147b48a3fe7ebc021b12a 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Android.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 62cfc084b27a4d14b8e708d5d2631881 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Android/OpenIAB_Android.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using System.Collections; 19 | using System.Collections.Generic; 20 | using System; 21 | 22 | namespace OnePF 23 | { 24 | /** 25 | * Android billing implentation 26 | */ 27 | public class OpenIAB_Android 28 | #if UNITY_ANDROID 29 | : IOpenIAB 30 | #endif 31 | { 32 | public static readonly string STORE_GOOGLE; 33 | public static readonly string STORE_AMAZON; 34 | public static readonly string STORE_SAMSUNG; 35 | public static readonly string STORE_NOKIA; 36 | public static readonly string STORE_SKUBIT; 37 | public static readonly string STORE_SKUBIT_TEST; 38 | public static readonly string STORE_YANDEX; 39 | public static readonly string STORE_APPLAND; 40 | public static readonly string STORE_SLIDEME; 41 | public static readonly string STORE_APTOIDE; 42 | 43 | #if UNITY_ANDROID 44 | private static AndroidJavaObject _plugin; 45 | 46 | IntPtr ConvertToStringJNIArray(string[] array) 47 | { 48 | IntPtr stringClass = AndroidJNI.FindClass("java/lang/String"); 49 | IntPtr initialString = AndroidJNI.NewStringUTF(""); 50 | IntPtr javaStringArray = AndroidJNI.NewObjectArray(array.Length, stringClass, initialString); 51 | 52 | for (int i = 0; i < array.Length; ++i) 53 | { 54 | AndroidJNI.SetObjectArrayElement(javaStringArray, i, AndroidJNI.NewStringUTF(array[i])); 55 | } 56 | 57 | return javaStringArray; 58 | } 59 | 60 | static OpenIAB_Android() 61 | { 62 | if (Application.platform != RuntimePlatform.Android) 63 | { 64 | STORE_GOOGLE = "STORE_GOOGLE"; 65 | STORE_AMAZON = "STORE_AMAZON"; 66 | STORE_SAMSUNG = "STORE_SAMSUNG"; 67 | STORE_NOKIA = "STORE_NOKIA"; 68 | STORE_SKUBIT = "STORE_SKUBIT"; 69 | STORE_SKUBIT_TEST = "STORE_SKUBIT_TEST"; 70 | STORE_YANDEX = "STORE_YANDEX"; 71 | STORE_APPLAND = "STORE_APPLAND"; 72 | STORE_SLIDEME = "STORE_SLIDEME"; 73 | STORE_APTOIDE = "STORE_APTOIDE"; 74 | return; 75 | } 76 | 77 | AndroidJNI.AttachCurrentThread(); 78 | 79 | // Find the plugin instance 80 | using (var pluginClass = new AndroidJavaClass("org.onepf.openiab.UnityPlugin")) 81 | { 82 | _plugin = pluginClass.CallStatic("instance"); 83 | } 84 | 85 | using (var pluginClass = new AndroidJavaClass("org.onepf.oms.OpenIabHelper")) 86 | { 87 | STORE_GOOGLE = pluginClass.GetStatic("NAME_GOOGLE"); 88 | STORE_AMAZON = pluginClass.GetStatic("NAME_AMAZON"); 89 | STORE_SAMSUNG = pluginClass.GetStatic("NAME_SAMSUNG"); 90 | STORE_NOKIA = pluginClass.GetStatic("NAME_NOKIA"); 91 | STORE_SKUBIT = pluginClass.GetStatic("NAME_SKUBIT"); 92 | STORE_SKUBIT_TEST = pluginClass.GetStatic("NAME_SKUBIT_TEST"); 93 | STORE_YANDEX = pluginClass.GetStatic("NAME_YANDEX"); 94 | STORE_APPLAND = pluginClass.GetStatic("NAME_APPLAND"); 95 | STORE_SLIDEME = pluginClass.GetStatic("NAME_SLIDEME"); 96 | STORE_APTOIDE = pluginClass.GetStatic("NAME_APTOIDE"); 97 | } 98 | } 99 | 100 | private bool IsDevice() 101 | { 102 | if (Application.platform != RuntimePlatform.Android) 103 | { 104 | //OpenIAB.EventManager.SendMessage("OnBillingNotSupported", "editor mode"); 105 | return false; 106 | } 107 | return true; 108 | } 109 | 110 | private AndroidJavaObject CreateJavaHashMap(Dictionary storeKeys) 111 | { 112 | var j_HashMap = new AndroidJavaObject("java.util.HashMap"); 113 | IntPtr method_Put = AndroidJNIHelper.GetMethodID(j_HashMap.GetRawClass(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); 114 | 115 | if (storeKeys != null) 116 | { 117 | object[] args = new object[2]; 118 | foreach (KeyValuePair kvp in storeKeys) 119 | { 120 | using (AndroidJavaObject k = new AndroidJavaObject("java.lang.String", kvp.Key)) 121 | { 122 | using (AndroidJavaObject v = new AndroidJavaObject("java.lang.String", kvp.Value)) 123 | { 124 | args[0] = k; 125 | args[1] = v; 126 | AndroidJNI.CallObjectMethod(j_HashMap.GetRawObject(), 127 | method_Put, AndroidJNIHelper.CreateJNIArgArray(args)); 128 | } 129 | } 130 | } 131 | } 132 | return j_HashMap; 133 | } 134 | 135 | public void init(Options options) 136 | { 137 | if (!IsDevice()) 138 | { 139 | // Fake init process in the editor. For test purposes 140 | OpenIAB.EventManager.SendMessage("OnBillingSupported", ""); 141 | return; 142 | } 143 | 144 | using (var j_optionsBuilder = new AndroidJavaObject("org.onepf.oms.OpenIabHelper$Options$Builder")) 145 | { 146 | var clazz = j_optionsBuilder.GetRawClass(); 147 | var objPtr = j_optionsBuilder.GetRawObject(); 148 | 149 | j_optionsBuilder.Call("setDiscoveryTimeout", options.discoveryTimeoutMs) 150 | .Call("setCheckInventory", options.checkInventory) 151 | .Call("setCheckInventoryTimeout", options.checkInventoryTimeoutMs) 152 | .Call("setVerifyMode", (int) options.verifyMode) 153 | .Call("setStoreSearchStrategy", (int) options.storeSearchStrategy); 154 | 155 | if (options.samsungCertificationRequestCode > 0) 156 | j_optionsBuilder.Call("setSamsungCertificationRequestCode", options.samsungCertificationRequestCode); 157 | 158 | foreach (var pair in options.storeKeys) 159 | j_optionsBuilder.Call("addStoreKey", pair.Key, pair.Value); 160 | 161 | var addPreferredStoreNameMethod = AndroidJNI.GetMethodID(clazz, "addPreferredStoreName", "([Ljava/lang/String;)Lorg/onepf/oms/OpenIabHelper$Options$Builder;"); 162 | var prms = new jvalue[1]; 163 | prms[0].l = ConvertToStringJNIArray(options.prefferedStoreNames); 164 | AndroidJNI.CallObjectMethod(objPtr, addPreferredStoreNameMethod, prms); 165 | 166 | var addAvailableStoreNameMethod = AndroidJNI.GetMethodID(clazz, "addAvailableStoreNames", "([Ljava/lang/String;)Lorg/onepf/oms/OpenIabHelper$Options$Builder;"); 167 | prms = new jvalue[1]; 168 | prms[0].l = ConvertToStringJNIArray(options.availableStoreNames); 169 | AndroidJNI.CallObjectMethod(objPtr, addAvailableStoreNameMethod, prms); 170 | 171 | // Build options instance 172 | var buildMethod = AndroidJNI.GetMethodID(clazz, "build", "()Lorg/onepf/oms/OpenIabHelper$Options;"); 173 | var j_options = AndroidJNI.CallObjectMethod(objPtr, buildMethod, new jvalue[0]); 174 | 175 | // UnityPlugin.initWithOptions(OpenIabHelper.Options options); 176 | var initWithOptionsMethod = AndroidJNI.GetMethodID(_plugin.GetRawClass(), "initWithOptions", "(Lorg/onepf/oms/OpenIabHelper$Options;)V"); 177 | prms = new jvalue[1]; 178 | prms[0].l = j_options; 179 | AndroidJNI.CallVoidMethod(_plugin.GetRawObject(), initWithOptionsMethod, prms); 180 | } 181 | } 182 | 183 | public void init(Dictionary storeKeys = null) 184 | { 185 | if (!IsDevice()) return; 186 | 187 | if (storeKeys != null) 188 | { 189 | AndroidJavaObject j_storeKeys = CreateJavaHashMap(storeKeys); 190 | _plugin.Call("init", j_storeKeys); 191 | j_storeKeys.Dispose(); 192 | } 193 | } 194 | 195 | public void mapSku(string sku, string storeName, string storeSku) 196 | { 197 | if (!IsDevice()) return; 198 | 199 | _plugin.Call("mapSku", sku, storeName, storeSku); 200 | } 201 | 202 | public void unbindService() 203 | { 204 | if (IsDevice()) 205 | { 206 | _plugin.Call("unbindService"); 207 | } 208 | } 209 | 210 | public bool areSubscriptionsSupported() 211 | { 212 | if (!IsDevice()) 213 | { 214 | // Fake result for editor mode 215 | return true; 216 | } 217 | return _plugin.Call("areSubscriptionsSupported"); 218 | } 219 | 220 | public void queryInventory() 221 | { 222 | if (!IsDevice()) 223 | { 224 | return; 225 | } 226 | IntPtr methodId = AndroidJNI.GetMethodID(_plugin.GetRawClass(), "queryInventory", "()V"); 227 | AndroidJNI.CallVoidMethod(_plugin.GetRawObject(), methodId, new jvalue[] { }); 228 | } 229 | 230 | public void queryInventory(string[] skus) 231 | { 232 | queryInventory(skus, skus); 233 | } 234 | 235 | private void queryInventory(string[] inAppSkus, string[] subsSkus) 236 | { 237 | if (!IsDevice()) 238 | { 239 | return; 240 | } 241 | 242 | jvalue[] args = new jvalue[2]; 243 | args[0].l = ConvertToStringJNIArray(inAppSkus); 244 | args[1].l = ConvertToStringJNIArray(subsSkus); 245 | 246 | IntPtr methodId = AndroidJNI.GetMethodID(_plugin.GetRawClass(), "queryInventory", "([Ljava/lang/String;[Ljava/lang/String;)V"); 247 | AndroidJNI.CallVoidMethod(_plugin.GetRawObject(), methodId, args); 248 | } 249 | 250 | public void purchaseProduct(string sku, string developerPayload = "") 251 | { 252 | if (!IsDevice()) 253 | { 254 | // Fake purchase in editor mode 255 | OpenIAB.EventManager.SendMessage("OnPurchaseSucceeded", Purchase.CreateFromSku(sku, developerPayload).Serialize()); 256 | return; 257 | } 258 | _plugin.Call("purchaseProduct", sku, developerPayload); 259 | } 260 | 261 | public void purchaseSubscription(string sku, string developerPayload = "") 262 | { 263 | if (!IsDevice()) 264 | { 265 | // Fake purchase in editor mode 266 | OpenIAB.EventManager.SendMessage("OnPurchaseSucceeded", Purchase.CreateFromSku(sku, developerPayload).Serialize()); 267 | return; 268 | } 269 | _plugin.Call("purchaseSubscription", sku, developerPayload); 270 | } 271 | 272 | public void consumeProduct(Purchase purchase) 273 | { 274 | if (!IsDevice()) 275 | { 276 | // Fake consume in editor mode 277 | OpenIAB.EventManager.SendMessage("OnConsumePurchaseSucceeded", purchase.Serialize()); 278 | return; 279 | } 280 | _plugin.Call("consumeProduct", purchase.Serialize()); 281 | } 282 | 283 | public void restoreTransactions() 284 | { 285 | } 286 | 287 | public bool isDebugLog() 288 | { 289 | return _plugin.Call("isDebugLog"); 290 | } 291 | 292 | public void enableDebugLogging(bool enabled) 293 | { 294 | _plugin.Call("enableDebugLogging", enabled); 295 | } 296 | 297 | public void enableDebugLogging(bool enabled, string tag) 298 | { 299 | _plugin.Call("enableDebugLogging", enabled, tag); 300 | } 301 | #else 302 | static OpenIAB_Android() { 303 | STORE_GOOGLE = "STORE_GOOGLE"; 304 | STORE_AMAZON = "STORE_AMAZON"; 305 | STORE_SAMSUNG = "STORE_SAMSUNG"; 306 | STORE_NOKIA = "STORE_NOKIA"; 307 | STORE_YANDEX = "STORE_YANDEX"; 308 | } 309 | #endif 310 | } 311 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Android/OpenIAB_Android.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 99f4db99136ac744ab35bf95b8ef7e50 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/IOpenIAB.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using System.Collections; 19 | using System.Collections.Generic; 20 | 21 | namespace OnePF 22 | { 23 | /** 24 | * Implement this to create billing service for new platform 25 | */ 26 | public interface IOpenIAB 27 | { 28 | void init(Options options); 29 | void mapSku(string sku, string storeName, string storeSku); 30 | void unbindService(); 31 | bool areSubscriptionsSupported(); 32 | void queryInventory(); 33 | void queryInventory(string[] inAppSkus); 34 | void purchaseProduct(string sku, string developerPayload = ""); 35 | void purchaseSubscription(string sku, string developerPayload = ""); 36 | void consumeProduct(Purchase purchase); 37 | void restoreTransactions(); 38 | 39 | bool isDebugLog(); 40 | void enableDebugLogging(bool enabled); 41 | void enableDebugLogging(bool enabled, string tag); 42 | } 43 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/IOpenIAB.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f6b21a20f0f8ef54eab974f3c6229368 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Inventory.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | using UnityEngine; 22 | 23 | namespace OnePF 24 | { 25 | /** 26 | * Container for finished purchases and store listings 27 | */ 28 | public class Inventory 29 | { 30 | private Dictionary _skuMap = new Dictionary(); 31 | private Dictionary _purchaseMap = new Dictionary(); 32 | 33 | public Inventory(string json) 34 | { 35 | var j = new JSON(json); 36 | foreach (var entry in (List) j.fields["purchaseMap"]) 37 | { 38 | List pair = (List) entry; 39 | #if UNITY_IOS 40 | string key = OpenIAB_iOS.StoreSku2Sku(pair[0].ToString()); 41 | // TODO: use same cotr on all platforms. Test why it works on Android json 42 | Purchase value = new Purchase((JSON) pair[1]); 43 | #else 44 | string key = pair[0].ToString(); 45 | Purchase value = new Purchase(pair[1].ToString()); 46 | #endif 47 | _purchaseMap.Add(key, value); 48 | } 49 | foreach (var entry in (List) j.fields["skuMap"]) 50 | { 51 | List pair = (List) entry; 52 | #if UNITY_IOS 53 | string key = OpenIAB_iOS.StoreSku2Sku(pair[0].ToString()); 54 | SkuDetails value = new SkuDetails((JSON) pair[1]); 55 | #else 56 | string key = pair[0].ToString(); 57 | SkuDetails value = new SkuDetails(pair[1].ToString()); 58 | #endif 59 | _skuMap.Add(key, value); 60 | } 61 | } 62 | 63 | #if UNITY_WP8 64 | public Inventory() 65 | { 66 | } 67 | #endif 68 | 69 | public override string ToString() 70 | { 71 | StringBuilder str = new StringBuilder(); 72 | str.Append("{purchaseMap:{"); 73 | foreach (var pair in _purchaseMap) 74 | { 75 | str.Append("\"" + pair.Key + "\":{" + pair.Value.ToString() + "},"); 76 | } 77 | str.Append("},"); 78 | str.Append("skuMap:{"); 79 | foreach (var pair in _skuMap) 80 | { 81 | str.Append("\"" + pair.Key + "\":{" + pair.Value.ToString() + "},"); 82 | } 83 | str.Append("}}"); 84 | return str.ToString(); 85 | } 86 | 87 | /** 88 | * Returns the listing details for an in-app product. 89 | */ 90 | public SkuDetails GetSkuDetails(string sku) 91 | { 92 | if (!_skuMap.ContainsKey(sku)) 93 | { 94 | return null; 95 | } 96 | return _skuMap[sku]; 97 | } 98 | 99 | /** 100 | * Returns purchase information for a given product, or null if there is no purchase. 101 | */ 102 | public Purchase GetPurchase(string sku) 103 | { 104 | if (!_purchaseMap.ContainsKey(sku)) 105 | { 106 | return null; 107 | } 108 | return _purchaseMap[sku]; 109 | } 110 | 111 | /** 112 | * Returns whether or not there exists a purchase of the given product. 113 | */ 114 | public bool HasPurchase(string sku) 115 | { 116 | return _purchaseMap.ContainsKey(sku); 117 | } 118 | 119 | /** 120 | * Return whether or not details about the given product are available. 121 | */ 122 | public bool HasDetails(string sku) 123 | { 124 | return _skuMap.ContainsKey(sku); 125 | } 126 | 127 | /** 128 | * Erase a purchase (locally) from the inventory, given its product ID. This just 129 | * modifies the Inventory object locally and has no effect on the server! This is 130 | * useful when you have an existing Inventory object which you know to be up to date, 131 | * and you have just consumed an item successfully, which means that erasing its 132 | * purchase data from the Inventory you already have is quicker than querying for 133 | * a new Inventory. 134 | */ 135 | public void ErasePurchase(string sku) 136 | { 137 | if (_purchaseMap.ContainsKey(sku)) _purchaseMap.Remove(sku); 138 | } 139 | 140 | /** 141 | * Returns a list of all owned product IDs. 142 | */ 143 | public List GetAllOwnedSkus() 144 | { 145 | return _purchaseMap.Keys.ToList(); 146 | } 147 | 148 | /** 149 | * Returns a list of all owned product IDs of a given type 150 | */ 151 | public List GetAllOwnedSkus(string itemType) 152 | { 153 | List result = new List(); 154 | foreach (Purchase p in _purchaseMap.Values) 155 | { 156 | if (p.ItemType == itemType) result.Add(p.Sku); 157 | } 158 | return result; 159 | } 160 | 161 | /** 162 | * Returns a list of all purchases. 163 | */ 164 | public List GetAllPurchases() 165 | { 166 | return _purchaseMap.Values.ToList(); 167 | } 168 | 169 | /** 170 | * Returns a list of all available {@code SkuDetails} products. 171 | */ 172 | public List GetAllAvailableSkus() 173 | { 174 | return _skuMap.Values.ToList(); 175 | } 176 | 177 | public void AddSkuDetails(SkuDetails d) 178 | { 179 | _skuMap.Add(d.Sku, d); 180 | } 181 | 182 | public void AddPurchase(Purchase p) 183 | { 184 | _purchaseMap.Add(p.Sku, p); 185 | } 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Inventory.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9a5d57d3e18969d4398f66b3a76351a1 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/JSON.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d28eaa2086b58c24590b2e30ebb4b125 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/OpenIAB.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using System.Collections; 19 | using System.Collections.Generic; 20 | using System; 21 | 22 | namespace OnePF 23 | { 24 | /** 25 | * Main class 26 | */ 27 | public class OpenIAB 28 | { 29 | public static GameObject EventManager { get { return GameObject.Find(typeof(OpenIABEventManager).ToString()); } } 30 | 31 | static IOpenIAB _billing; 32 | 33 | /** 34 | * Static constructor 35 | * Creates billing instance 36 | */ 37 | static OpenIAB() 38 | { 39 | #if UNITY_ANDROID 40 | _billing = new OpenIAB_Android(); 41 | Debug.Log("********** Android OpenIAB plugin initialized **********"); 42 | #elif UNITY_IOS 43 | _billing = new OpenIAB_iOS(); 44 | Debug.Log("********** iOS OpenIAB plugin initialized **********"); 45 | #elif UNITY_WP8 46 | _billing = new OpenIAB_WP8(); 47 | Debug.Log("********** WP8 OpenIAB plugin initialized **********"); 48 | #else 49 | Debug.LogError("OpenIAB billing currently not supported on this platform. Sorry."); 50 | #endif 51 | } 52 | 53 | /** 54 | * Must be only called before init 55 | * @param sku product ID 56 | * @param storeName name of the store 57 | * @param storeSku product ID in the store 58 | */ 59 | public static void mapSku(string sku, string storeName, string storeSku) 60 | { 61 | _billing.mapSku(sku, storeName, storeSku); 62 | } 63 | 64 | /** 65 | * Starts up the billing service. This will also check to see if in app billing is supported and fire the appropriate event 66 | * @param options library options instance 67 | */ 68 | public static void init(Options options) 69 | { 70 | _billing.init(options); 71 | } 72 | 73 | /** 74 | * Unbinds and shuts down the billing service 75 | */ 76 | public static void unbindService() 77 | { 78 | _billing.unbindService(); 79 | } 80 | 81 | /** 82 | * Checks if subscriptions are supported. Currently used only on Android 83 | * @return true if subscriptions are supported on the device 84 | */ 85 | public static bool areSubscriptionsSupported() 86 | { 87 | return _billing.areSubscriptionsSupported(); 88 | } 89 | 90 | /** 91 | * Sends a request to get all completed purchases 92 | */ 93 | public static void queryInventory() 94 | { 95 | _billing.queryInventory(); 96 | } 97 | 98 | /** 99 | * Sends a request to get all completed purchases and specified skus information 100 | * @param skus product IDs 101 | */ 102 | public static void queryInventory(string[] skus) 103 | { 104 | _billing.queryInventory(skus); 105 | } 106 | 107 | /** 108 | * Purchases the product with the given sku and developerPayload 109 | * @param product ID 110 | * @param developerPayload payload to verify transaction 111 | */ 112 | public static void purchaseProduct(string sku, string developerPayload = "") 113 | { 114 | _billing.purchaseProduct(sku, developerPayload); 115 | } 116 | 117 | /** 118 | * Purchases the subscription with the given sku and developerPayload 119 | * @param sku product ID 120 | * @param developerPayload payload to verify transaction 121 | */ 122 | public static void purchaseSubscription(string sku, string developerPayload = "") 123 | { 124 | _billing.purchaseSubscription(sku, developerPayload); 125 | } 126 | 127 | /** 128 | * Sends out a request to consume the product 129 | * @param purchase purchase data holder 130 | */ 131 | public static void consumeProduct(Purchase purchase) 132 | { 133 | _billing.consumeProduct(purchase); 134 | } 135 | 136 | /** 137 | * Restore purchased items. iOS AppStore requirement 138 | */ 139 | public static void restoreTransactions() 140 | { 141 | _billing.restoreTransactions(); 142 | } 143 | 144 | /** 145 | * Is verbose logging enabled 146 | * @return true if logging is enabled 147 | */ 148 | public static bool isDebugLog() 149 | { 150 | return _billing.isDebugLog(); 151 | } 152 | 153 | /** 154 | * Get more debug information 155 | * @param enabled if logging is enabled 156 | */ 157 | public static void enableDebugLogging(bool enabled) 158 | { 159 | _billing.enableDebugLogging(enabled); 160 | } 161 | 162 | /** 163 | * Get more debug information 164 | * @param enabled if logging is enabled 165 | * @param tag Android log tag 166 | */ 167 | public static void enableDebugLogging(bool enabled, string tag) 168 | { 169 | _billing.enableDebugLogging(enabled, tag); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/OpenIAB.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 92e6a86c280999944a4b4bee959bd369 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/OpenIABEventManager.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using System; 19 | using System.Collections; 20 | using System.Collections.Generic; 21 | using OnePF; 22 | 23 | /** 24 | * Simple event manager. Subscribe to handle billing events 25 | */ 26 | public class OpenIABEventManager : MonoBehaviour 27 | { 28 | /** 29 | * Successfull Init callback. Billing is supported on current platform 30 | */ 31 | public static event Action billingSupportedEvent; 32 | 33 | /** 34 | * Failed Init callback. Billing is not supported on current platform 35 | */ 36 | public static event Action billingNotSupportedEvent; 37 | 38 | /** 39 | * Successful QueryInventory callback. Purchase history and store listings are returned 40 | */ 41 | public static event Action queryInventorySucceededEvent; 42 | 43 | /** 44 | * Failed QueryInventory callback. 45 | */ 46 | public static event Action queryInventoryFailedEvent; 47 | 48 | /** 49 | * Successful purchase callback. Fired after purchase of a product or a subscription 50 | */ 51 | public static event Action purchaseSucceededEvent; 52 | 53 | /** 54 | * Failed purchase callback 55 | */ 56 | public static event Action purchaseFailedEvent; 57 | 58 | /** 59 | * Successful consume attempt callback 60 | */ 61 | public static event Action consumePurchaseSucceededEvent; 62 | 63 | /** 64 | * Failed consume attempt callback 65 | */ 66 | public static event Action consumePurchaseFailedEvent; 67 | 68 | #pragma warning disable 0067 69 | /** 70 | * Fired when transaction was restored 71 | */ 72 | public static event Action transactionRestoredEvent; 73 | 74 | /** 75 | * Fired when transaction restoration process failed 76 | */ 77 | public static event Action restoreFailedEvent; 78 | 79 | /** 80 | * Fired when transaction restoration process succeeded 81 | */ 82 | public static event Action restoreSucceededEvent; 83 | #pragma warning restore 0067 84 | 85 | private void Awake() 86 | { 87 | // Set the GameObject name to the class name for easy access from native plugin 88 | gameObject.name = GetType().ToString(); 89 | DontDestroyOnLoad(this); 90 | } 91 | 92 | #if UNITY_ANDROID 93 | private void OnMapSkuFailed(string exception) 94 | { 95 | Debug.LogError("SKU mapping failed: " + exception); 96 | } 97 | 98 | private void OnBillingSupported(string empty) 99 | { 100 | if (billingSupportedEvent != null) 101 | billingSupportedEvent(); 102 | } 103 | 104 | private void OnBillingNotSupported(string error) 105 | { 106 | if (billingNotSupportedEvent != null) 107 | billingNotSupportedEvent(error); 108 | } 109 | 110 | private void OnQueryInventorySucceeded(string json) 111 | { 112 | if (queryInventorySucceededEvent != null) 113 | { 114 | Inventory inventory = new Inventory(json); 115 | queryInventorySucceededEvent(inventory); 116 | } 117 | } 118 | 119 | private void OnQueryInventoryFailed(string error) 120 | { 121 | if (queryInventoryFailedEvent != null) 122 | queryInventoryFailedEvent(error); 123 | } 124 | 125 | private void OnPurchaseSucceeded(string json) 126 | { 127 | if (purchaseSucceededEvent != null) 128 | purchaseSucceededEvent(new Purchase(json)); 129 | } 130 | 131 | private void OnPurchaseFailed(string message) 132 | { 133 | int errorCode = -1; 134 | string errorMessage = "Unknown error"; 135 | 136 | if (!string.IsNullOrEmpty(message)) { 137 | string[] tokens = message.Split('|'); 138 | 139 | if (tokens.Length >= 2) { 140 | Int32.TryParse(tokens[0], out errorCode); 141 | errorMessage = tokens[1]; 142 | } else { 143 | errorMessage = message; 144 | } 145 | } 146 | if (purchaseFailedEvent != null) 147 | purchaseFailedEvent(errorCode, errorMessage); 148 | } 149 | 150 | private void OnConsumePurchaseSucceeded(string json) 151 | { 152 | if (consumePurchaseSucceededEvent != null) 153 | consumePurchaseSucceededEvent(new Purchase(json)); 154 | } 155 | 156 | private void OnConsumePurchaseFailed(string error) 157 | { 158 | if (consumePurchaseFailedEvent != null) 159 | consumePurchaseFailedEvent(error); 160 | } 161 | 162 | public void OnTransactionRestored(string json) 163 | { 164 | if (transactionRestoredEvent != null) 165 | { 166 | transactionRestoredEvent(new Purchase(json)); 167 | } 168 | } 169 | 170 | public void OnRestoreTransactionFailed(string error) 171 | { 172 | if (restoreFailedEvent != null) 173 | { 174 | restoreFailedEvent(error); 175 | } 176 | } 177 | 178 | public void OnRestoreTransactionSucceeded(string message) 179 | { 180 | if (restoreSucceededEvent != null) 181 | { 182 | restoreSucceededEvent(); 183 | } 184 | } 185 | #endif 186 | 187 | #if UNITY_IOS 188 | private void OnBillingSupported(string empty) 189 | { 190 | if (billingSupportedEvent != null) 191 | { 192 | billingSupportedEvent(); 193 | } 194 | } 195 | 196 | private void OnBillingNotSupported(string error) 197 | { 198 | if (billingNotSupportedEvent != null) 199 | billingNotSupportedEvent(error); 200 | } 201 | 202 | private void OnQueryInventorySucceeded(string json) 203 | { 204 | if (queryInventorySucceededEvent != null) 205 | { 206 | Inventory inventory = new Inventory(json); 207 | queryInventorySucceededEvent(inventory); 208 | } 209 | } 210 | 211 | private void OnQueryInventoryFailed(string error) 212 | { 213 | if (queryInventoryFailedEvent != null) 214 | queryInventoryFailedEvent(error); 215 | } 216 | 217 | private void OnPurchaseSucceeded(string json) 218 | { 219 | if (purchaseSucceededEvent != null) 220 | { 221 | purchaseSucceededEvent(new Purchase(json)); 222 | } 223 | } 224 | 225 | private void OnPurchaseFailed(string error) 226 | { 227 | if (purchaseFailedEvent != null) 228 | { 229 | // -1005 is similar to android "cancelled" code 230 | purchaseFailedEvent(string.Equals(error, "Transaction cancelled")? -1005 : -1, error); 231 | } 232 | } 233 | 234 | private void OnConsumePurchaseSucceeded(string json) 235 | { 236 | if (consumePurchaseSucceededEvent != null) 237 | consumePurchaseSucceededEvent(new Purchase(json)); 238 | } 239 | 240 | private void OnConsumePurchaseFailed(string error) 241 | { 242 | if (consumePurchaseFailedEvent != null) 243 | consumePurchaseFailedEvent(error); 244 | } 245 | 246 | public void OnPurchaseRestored(string json) 247 | { 248 | if (transactionRestoredEvent != null) 249 | { 250 | transactionRestoredEvent(new Purchase(json)); 251 | } 252 | } 253 | 254 | public void OnRestoreFailed(string error) 255 | { 256 | if (restoreFailedEvent != null) 257 | { 258 | restoreFailedEvent(error); 259 | } 260 | } 261 | 262 | public void OnRestoreFinished(string message) 263 | { 264 | if (restoreSucceededEvent != null) 265 | { 266 | restoreSucceededEvent(); 267 | } 268 | } 269 | #endif 270 | 271 | #if UNITY_WP8 272 | public void OnBillingSupported() 273 | { 274 | if (billingSupportedEvent != null) 275 | billingSupportedEvent(); 276 | } 277 | 278 | public void OnBillingNotSupported(string error) 279 | { 280 | if (billingNotSupportedEvent != null) 281 | billingNotSupportedEvent(error); 282 | } 283 | 284 | private void OnQueryInventorySucceeded(Inventory inventory) 285 | { 286 | if (queryInventorySucceededEvent != null) 287 | queryInventorySucceededEvent(inventory); 288 | } 289 | 290 | private void OnQueryInventoryFailed(string error) 291 | { 292 | if (queryInventoryFailedEvent != null) 293 | queryInventoryFailedEvent(error); 294 | } 295 | 296 | private void OnPurchaseSucceeded(Purchase purchase) 297 | { 298 | if (purchaseSucceededEvent != null) 299 | purchaseSucceededEvent(purchase); 300 | } 301 | 302 | private void OnPurchaseFailed(string error) 303 | { 304 | if (purchaseFailedEvent != null) 305 | purchaseFailedEvent(-1, error); 306 | } 307 | 308 | private void OnConsumePurchaseSucceeded(Purchase purchase) 309 | { 310 | if (consumePurchaseSucceededEvent != null) 311 | consumePurchaseSucceededEvent(purchase); 312 | } 313 | 314 | private void OnConsumePurchaseFailed(string error) 315 | { 316 | if (consumePurchaseFailedEvent != null) 317 | consumePurchaseFailedEvent(error); 318 | } 319 | #endif 320 | } 321 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/OpenIABEventManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63d9ab6456c839448bd269e6b3c831ae 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Options.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using System.Collections.Generic; 18 | 19 | namespace OnePF 20 | { 21 | /** 22 | * All options of OpenIAB can be found here 23 | */ 24 | public class Options 25 | { 26 | /** 27 | * Default timeout (in milliseconds) for discover all OpenStores on device. 28 | */ 29 | public const int DISCOVER_TIMEOUT_MS = 5000; 30 | 31 | /** 32 | * For generic stores it takes 1.5 - 3sec 33 | * SamsungApps initialization is very time consuming (from 4 to 12 seconds). 34 | */ 35 | public const int INVENTORY_CHECK_TIMEOUT_MS = 10000; 36 | 37 | /** 38 | * Wait specified amount of ms to find all OpenStores on device 39 | */ 40 | public int discoveryTimeoutMs = DISCOVER_TIMEOUT_MS; 41 | 42 | /** 43 | * Check user inventory in every store to select proper store 44 | *

45 | * Will try to connect to each billingService and extract user's purchases. 46 | * If purchases have been found in the only store that store will be used for further purchases. 47 | * If purchases have been found in multiple stores only such stores will be used for further elections 48 | */ 49 | public bool checkInventory = true; 50 | 51 | /** 52 | * Wait specified amount of ms to check inventory in all stores 53 | */ 54 | public int checkInventoryTimeoutMs = INVENTORY_CHECK_TIMEOUT_MS; 55 | 56 | /** 57 | * OpenIAB could skip receipt verification by publicKey for GooglePlay and OpenStores 58 | *

59 | * Receipt could be verified in {@link OnIabPurchaseFinishedListener#onIabPurchaseFinished()} 60 | * using {@link Purchase#getOriginalJson()} and {@link Purchase#getSignature()} 61 | */ 62 | public OptionsVerifyMode verifyMode = OptionsVerifyMode.VERIFY_EVERYTHING; 63 | 64 | public SearchStrategy storeSearchStrategy = SearchStrategy.INSTALLER; 65 | 66 | /** 67 | * storeKeys is map of [ appstore name -> publicKeyBase64 ] 68 | * Put keys for all stores you support in this Map and pass it to instantiate {@link OpenIabHelper} 69 | *

70 | * publicKey key is used to verify receipt is created by genuine Appstore using 71 | * provided signature. It can be found in Developer Console of particular store 72 | *

73 | * name of particular store can be provided by local_store tool if you run it on device. 74 | * For Google Play OpenIAB uses {@link OpenIabHelper#NAME_GOOGLE}. 75 | *

76 | *

Note: 77 | * AmazonApps and SamsungApps doesn't use RSA keys for receipt verification, so you don't need 78 | * to specify it 79 | */ 80 | public Dictionary storeKeys = new Dictionary(); 81 | 82 | /** 83 | * Used as priority list if store that installed app is not found and there are 84 | * multiple stores installed on device that supports billing. 85 | */ 86 | public string[] prefferedStoreNames = new string[] { }; 87 | 88 | public string[] availableStoreNames = new string[] { }; 89 | 90 | public int samsungCertificationRequestCode; 91 | } 92 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Options.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bd9b556a698ef084ba1038e5ba2a572f 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/OptionsVerifyMode.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using System; 18 | using System.Collections.Generic; 19 | using System.Linq; 20 | using System.Text; 21 | 22 | namespace OnePF 23 | { 24 | public enum OptionsVerifyMode 25 | { 26 | /** 27 | * Verify signatures in any store. 28 | *

29 | * By default in Google's IabHelper. Throws exception if key is not available or invalid. 30 | * To prevent crashes OpenIAB wouldn't connect to OpenStore if no publicKey provided 31 | */ 32 | VERIFY_EVERYTHING = 0, 33 | 34 | /** 35 | * Don't verify signatires. To perform verification on server-side 36 | */ 37 | VERIFY_SKIP = 1, 38 | 39 | /** 40 | * Verify signatures only if publicKey is available. Otherwise skip verification. 41 | *

42 | * Developer is responsible for verify 43 | */ 44 | VERIFY_ONLY_KNOWN = 2 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/OptionsVerifyMode.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d923727ef887bf6458bd92253a836304 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Prefabs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4d9baf6f6e75c774fbb2853817688168 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Prefabs/OpenIABEventManager.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1 &100000 4 | GameObject: 5 | m_ObjectHideFlags: 0 6 | m_PrefabParentObject: {fileID: 0} 7 | m_PrefabInternal: {fileID: 100100000} 8 | serializedVersion: 4 9 | m_Component: 10 | - 4: {fileID: 400000} 11 | - 114: {fileID: 11400000} 12 | m_Layer: 0 13 | m_Name: OpenIABEventManager 14 | m_TagString: Untagged 15 | m_Icon: {fileID: 0} 16 | m_NavMeshLayer: 0 17 | m_StaticEditorFlags: 0 18 | m_IsActive: 1 19 | --- !u!4 &400000 20 | Transform: 21 | m_ObjectHideFlags: 1 22 | m_PrefabParentObject: {fileID: 0} 23 | m_PrefabInternal: {fileID: 100100000} 24 | m_GameObject: {fileID: 100000} 25 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 26 | m_LocalPosition: {x: 0, y: 0, z: 0} 27 | m_LocalScale: {x: 1, y: 1, z: 1} 28 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 29 | m_Children: [] 30 | m_Father: {fileID: 0} 31 | m_RootOrder: 0 32 | --- !u!114 &11400000 33 | MonoBehaviour: 34 | m_ObjectHideFlags: 1 35 | m_PrefabParentObject: {fileID: 0} 36 | m_PrefabInternal: {fileID: 100100000} 37 | m_GameObject: {fileID: 100000} 38 | m_Enabled: 1 39 | m_EditorHideFlags: 0 40 | m_Script: {fileID: 11500000, guid: 63d9ab6456c839448bd269e6b3c831ae, type: 3} 41 | m_Name: 42 | m_EditorClassIdentifier: 43 | --- !u!1001 &100100000 44 | Prefab: 45 | m_ObjectHideFlags: 1 46 | serializedVersion: 2 47 | m_Modification: 48 | m_TransformParent: {fileID: 0} 49 | m_Modifications: [] 50 | m_RemovedComponents: [] 51 | m_ParentPrefab: {fileID: 0} 52 | m_RootGameObject: {fileID: 100000} 53 | m_IsPrefabParent: 1 54 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Prefabs/OpenIABEventManager.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 90e394b0ec6b04c40a2ae2ae5977cd91 3 | NativeFormatImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Purchase.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | namespace OnePF 18 | { 19 | /** 20 | * Represents an in-app billing purchase. 21 | */ 22 | public class Purchase 23 | { 24 | ///

25 | /// ITEM_TYPE_INAPP or ITEM_TYPE_SUBS 26 | /// 27 | public string ItemType { get; private set; } 28 | /// 29 | /// A unique order identifier for the transaction. This corresponds to the Google Wallet Order ID. 30 | /// 31 | public string OrderId { get; private set; } 32 | /// 33 | /// The application package from which the purchase originated. 34 | /// 35 | public string PackageName { get; private set; } 36 | /// 37 | /// The item's product identifier. Every item has a product ID, which you must specify in the application's product list on the Google Play Developer Console. 38 | /// 39 | public string Sku { get; private set; } 40 | /// 41 | /// The time the product was purchased, in milliseconds since the epoch (Jan 1, 1970). 42 | /// 43 | public long PurchaseTime { get; private set; } 44 | /// 45 | /// The purchase state of the order. Possible values are 0 (purchased), 1 (canceled), or 2 (refunded). 46 | /// 47 | public int PurchaseState { get; private set; } 48 | /// 49 | /// A developer-specified string that contains supplemental information about an order. You can specify a value for this field when you make a getBuyIntent request. 50 | /// 51 | public string DeveloperPayload { get; private set; } 52 | /// 53 | /// A token that uniquely identifies a purchase for a given item and user pair. 54 | /// 55 | public string Token { get; private set; } 56 | /// 57 | /// JSON sent by the current store 58 | /// 59 | public string OriginalJson { get; private set; } 60 | /// 61 | /// Signature of the JSON string 62 | /// 63 | public string Signature { get; private set; } 64 | /// 65 | /// Current store name 66 | /// 67 | public string AppstoreName { get; private set; } 68 | /// 69 | /// Purchase Receipt of the order (iOS only) 70 | /// 71 | public string Receipt { get; private set;} 72 | 73 | private Purchase() 74 | { 75 | } 76 | 77 | /** 78 | * Create purchase from json string 79 | * @param jsonString data serialized to json 80 | */ 81 | public Purchase(string jsonString) 82 | { 83 | var json = new JSON(jsonString); 84 | ItemType = json.ToString("itemType"); 85 | OrderId = json.ToString("orderId"); 86 | PackageName = json.ToString("packageName"); 87 | Sku = json.ToString("sku"); 88 | PurchaseTime = json.ToLong("purchaseTime"); 89 | PurchaseState = json.ToInt("purchaseState"); 90 | DeveloperPayload = json.ToString("developerPayload"); 91 | Token = json.ToString("token"); 92 | OriginalJson = json.ToString("originalJson"); 93 | Signature = json.ToString("signature"); 94 | AppstoreName = json.ToString("appstoreName"); 95 | Receipt = json.ToString("receipt"); 96 | } 97 | 98 | #if UNITY_IOS 99 | public Purchase(JSON json) { 100 | ItemType = json.ToString("itemType"); 101 | OrderId = json.ToString("orderId"); 102 | Receipt = json.ToString("receipt"); 103 | PackageName = json.ToString("packageName"); 104 | Sku = json.ToString("sku"); 105 | PurchaseTime = json.ToLong("purchaseTime"); 106 | PurchaseState = json.ToInt("purchaseState"); 107 | DeveloperPayload = json.ToString("developerPayload"); 108 | Token = json.ToString("token"); 109 | OriginalJson = json.ToString("originalJson"); 110 | Signature = json.ToString("signature"); 111 | AppstoreName = json.ToString("appstoreName"); 112 | 113 | Sku = OpenIAB_iOS.StoreSku2Sku(Sku); 114 | } 115 | #endif 116 | 117 | /** 118 | * For debug purposes and editor mode 119 | * @param sku product ID 120 | */ 121 | public static Purchase CreateFromSku(string sku) 122 | { 123 | return CreateFromSku(sku, ""); 124 | } 125 | 126 | public static Purchase CreateFromSku(string sku, string developerPayload) 127 | { 128 | var p = new Purchase(); 129 | p.Sku = sku; 130 | p.DeveloperPayload = developerPayload; 131 | #if UNITY_IOS 132 | AddIOSHack(p); 133 | #endif 134 | return p; 135 | } 136 | 137 | /** 138 | * ToString 139 | * @return original json 140 | */ 141 | public override string ToString() 142 | { 143 | return "SKU:" + Sku + ";" + OriginalJson; 144 | } 145 | 146 | #if UNITY_IOS 147 | private static void AddIOSHack(Purchase p) { 148 | if(string.IsNullOrEmpty(p.AppstoreName)) { 149 | p.AppstoreName = "com.apple.appstore"; 150 | } 151 | if(string.IsNullOrEmpty(p.ItemType)) { 152 | p.ItemType = "InApp"; 153 | } 154 | if(string.IsNullOrEmpty(p.OrderId)) { 155 | p.OrderId = System.Guid.NewGuid().ToString(); 156 | } 157 | } 158 | #endif 159 | 160 | /** 161 | * Serilize to json 162 | * @return json string 163 | */ 164 | public string Serialize() 165 | { 166 | var j = new JSON(); 167 | j["itemType"] = ItemType; 168 | j["orderId"] = OrderId; 169 | j["packageName"] = PackageName; 170 | j["sku"] = Sku; 171 | j["purchaseTime"] = PurchaseTime; 172 | j["purchaseState"] = PurchaseState; 173 | j["developerPayload"] = DeveloperPayload; 174 | j["token"] = Token; 175 | j["originalJson"] = OriginalJson; 176 | j["signature"] = Signature; 177 | j["appstoreName"] = AppstoreName; 178 | j["receipt"] = Receipt; 179 | return j.serialized; 180 | } 181 | } 182 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/Purchase.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c3ae1c8b9811acb43bfa20906203afb2 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/SearchStrategy.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections; 3 | 4 | namespace OnePF 5 | { 6 | public enum SearchStrategy 7 | { 8 | INSTALLER = 0, 9 | BEST_FIT = 1, 10 | INSTALLER_THEN_BEST_FIT = 2 11 | } 12 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/SkuDetails.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | 19 | namespace OnePF 20 | { 21 | /** 22 | * Represents an in-app product's listing details. 23 | */ 24 | public class SkuDetails 25 | { 26 | public string ItemType { get; private set; } 27 | public string Sku { get; private set; } 28 | public string Type { get; private set; } 29 | public string Price { get; private set; } 30 | public string Title { get; private set; } 31 | public string Description { get; private set; } 32 | public string Json { get; private set; } 33 | public string CurrencyCode { get; private set; } 34 | public string PriceValue { get; private set; } 35 | 36 | // Used for Android 37 | public SkuDetails(string jsonString) 38 | { 39 | var json = new JSON(jsonString); 40 | ItemType = json.ToString("itemType"); 41 | Sku = json.ToString("sku"); 42 | Type = json.ToString("type"); 43 | Price = json.ToString("price"); 44 | Title = json.ToString("title"); 45 | Description = json.ToString("description"); 46 | Json = json.ToString("json"); 47 | CurrencyCode = json.ToString("currencyCode"); 48 | PriceValue = json.ToString("priceValue"); 49 | ParseFromJson(); 50 | } 51 | 52 | #if UNITY_IOS 53 | public SkuDetails(JSON json) { 54 | ItemType = json.ToString("itemType"); 55 | Sku = json.ToString("sku"); 56 | Type = json.ToString("type"); 57 | Price = json.ToString("price"); 58 | Title = json.ToString("title"); 59 | Description = json.ToString("description"); 60 | Json = json.ToString("json"); 61 | CurrencyCode = json.ToString("currencyCode"); 62 | PriceValue = json.ToString("priceValue"); 63 | 64 | Sku = OpenIAB_iOS.StoreSku2Sku(Sku); 65 | } 66 | #endif 67 | 68 | #if UNITY_WP8 69 | public SkuDetails(OnePF.WP8.ProductListing listing) 70 | { 71 | Sku = OpenIAB_WP8.GetSku(listing.ProductId); 72 | Title = listing.Name; 73 | Description = listing.Description; 74 | Price = listing.FormattedPrice; 75 | } 76 | #endif 77 | 78 | private void ParseFromJson() 79 | { 80 | if (string.IsNullOrEmpty(Json)) return; 81 | var json = new JSON(Json); 82 | if (string.IsNullOrEmpty(PriceValue)) 83 | { 84 | float val = json.ToFloat("price_amount_micros"); 85 | val /= 1000000; 86 | PriceValue = val.ToString(); 87 | } 88 | if (string.IsNullOrEmpty(CurrencyCode)) 89 | CurrencyCode = json.ToString("price_currency_code"); 90 | } 91 | 92 | /** 93 | * ToString 94 | * @return formatted string 95 | */ 96 | public override string ToString() 97 | { 98 | return string.Format("[SkuDetails: type = {0}, SKU = {1}, title = {2}, price = {3}, description = {4}, priceValue={5}, currency={6}]", 99 | ItemType, Sku, Title, Price, Description, PriceValue, CurrencyCode); 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/SkuDetails.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 05cc5ac966d741f409a884f35f62fa3a 3 | labels: 4 | - inapp 5 | - in-app 6 | - amazon 7 | - google 8 | - samsung 9 | - iap 10 | - Amazon 11 | - Google 12 | - Iap 13 | - In-app 14 | - Inapp 15 | - Samsung 16 | - billing 17 | - appstore 18 | - app-store 19 | - in 20 | - app 21 | - store 22 | - storekit 23 | - android 24 | - ios 25 | - purchase 26 | - onepf 27 | - open 28 | - opensource 29 | - source 30 | MonoImporter: 31 | serializedVersion: 2 32 | defaultReferences: [] 33 | executionOrder: 0 34 | icon: {instanceID: 0} 35 | userData: 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/WP8.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 52ccd8dd81cbd7d4aa0efca50bee9972 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/WP8/OpenIAB_WP8.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using System.Collections; 19 | using System.Collections.Generic; 20 | using System; 21 | #if UNITY_WP8 22 | using OnePF.WP8; 23 | #endif 24 | 25 | namespace OnePF 26 | { 27 | /** 28 | * Windows Phone 8 billing implementation 29 | */ 30 | public class OpenIAB_WP8 31 | #if UNITY_WP8 32 | : IOpenIAB 33 | #endif 34 | { 35 | public static readonly string STORE = "wp8_store"; /**< Windows Phone store constant */ 36 | 37 | #if UNITY_WP8 38 | 39 | static Dictionary _sku2storeSkuMappings = new Dictionary(); 40 | static Dictionary _storeSku2skuMappings = new Dictionary(); 41 | 42 | public static string GetSku(string storeSku) 43 | { 44 | return _storeSku2skuMappings.ContainsKey(storeSku) ? _storeSku2skuMappings[storeSku] : storeSku; 45 | } 46 | 47 | public static string GetStoreSku(string sku) 48 | { 49 | return _sku2storeSkuMappings.ContainsKey(sku) ? _sku2storeSkuMappings[sku] : sku; 50 | } 51 | 52 | static OpenIAB_WP8() 53 | { 54 | Store.PurchaseSucceeded += (storeSku, payload) => 55 | { 56 | string sku = GetSku(storeSku); 57 | Purchase purchase = Purchase.CreateFromSku(sku, payload); 58 | OpenIAB.EventManager.SendMessage("OnPurchaseSucceeded", purchase); 59 | }; 60 | Store.PurchaseFailed += (error) => { OpenIAB.EventManager.SendMessage("OnPurchaseFailed", error); }; 61 | 62 | Store.ConsumeSucceeded += (storeSku) => 63 | { 64 | string sku = GetSku(storeSku); 65 | Purchase purchase = Purchase.CreateFromSku(sku); 66 | OpenIAB.EventManager.SendMessage("OnConsumePurchaseSucceeded", purchase); 67 | }; 68 | Store.ConsumeFailed += (error) => { OpenIAB.EventManager.SendMessage("OnConsumePurchaseFailed", error); }; 69 | 70 | Store.LoadListingsSucceeded += (listings) => 71 | { 72 | Inventory inventory = GetInventory(); 73 | foreach (KeyValuePair pair in listings) 74 | { 75 | SkuDetails skuDetails = new SkuDetails(pair.Value); 76 | inventory.AddSkuDetails(skuDetails); 77 | } 78 | OpenIAB.EventManager.SendMessage("OnQueryInventorySucceeded", inventory); 79 | }; 80 | Store.LoadListingsFailed += (error) => 81 | { 82 | OpenIAB.EventManager.SendMessage("OnQueryInventoryFailed", error); 83 | }; 84 | } 85 | 86 | private static Inventory GetInventory() 87 | { 88 | var inventory = new Inventory(); 89 | var purchasesList = Store.Inventory; 90 | foreach (string storeSku in purchasesList) 91 | { 92 | Purchase purchase = Purchase.CreateFromSku(GetSku(storeSku)); 93 | inventory.AddPurchase(purchase); 94 | } 95 | return inventory; 96 | } 97 | 98 | public void init(Options options) 99 | { 100 | OpenIAB.EventManager.SendMessage("OnBillingSupported"); 101 | } 102 | 103 | public void mapSku(string sku, string storeName, string storeSku) 104 | { 105 | if (storeName == STORE) 106 | { 107 | _sku2storeSkuMappings[sku] = storeSku; 108 | _storeSku2skuMappings[storeSku] = sku; 109 | } 110 | } 111 | 112 | public void unbindService() 113 | { 114 | } 115 | 116 | public bool areSubscriptionsSupported() 117 | { 118 | return true; 119 | } 120 | 121 | public void queryInventory() 122 | { 123 | OpenIAB.EventManager.SendMessage("OnQueryInventorySucceeded", GetInventory()); 124 | } 125 | 126 | public void queryInventory(string[] skus) 127 | { 128 | string[] storeSkus = new string[skus.Length]; 129 | for (int i = 0; i < skus.Length; ++i) 130 | storeSkus[i] = GetStoreSku(skus[i]); 131 | Store.LoadListings(storeSkus); 132 | } 133 | 134 | public void purchaseProduct(string sku, string developerPayload = "") 135 | { 136 | string storeSku = GetStoreSku(sku); 137 | Store.PurchaseProduct(storeSku, developerPayload); 138 | } 139 | 140 | public void purchaseSubscription(string sku, string developerPayload = "") 141 | { 142 | purchaseProduct(sku, developerPayload); 143 | } 144 | 145 | public void consumeProduct(Purchase purchase) 146 | { 147 | string storeSku = GetStoreSku(purchase.Sku); 148 | Store.ConsumeProduct(storeSku); 149 | } 150 | 151 | /// 152 | /// Not needed on WP8 153 | /// 154 | public void restoreTransactions() 155 | { 156 | } 157 | 158 | public bool isDebugLog() 159 | { 160 | // TODO: implement in DLL 161 | return false; 162 | } 163 | 164 | public void enableDebugLogging(bool enabled) 165 | { 166 | // TODO: implement in DLL 167 | } 168 | 169 | public void enableDebugLogging(bool enabled, string tag) 170 | { 171 | // TODO: implement in DLL 172 | } 173 | #endif 174 | } 175 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/WP8/OpenIAB_WP8.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 24bee2735a13ca849a24d44b517234d0 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3273e231fb302e74393238c9c876f853 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/iOS/OpenIAB_iOS.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using UnityEngine; 18 | using System.Collections; 19 | using System.Collections.Generic; 20 | using System.Runtime.InteropServices; 21 | using System.Linq; 22 | 23 | namespace OnePF 24 | { 25 | /** 26 | * iOS AppStore billing implentation 27 | */ 28 | public class OpenIAB_iOS 29 | #if UNITY_IOS 30 | : IOpenIAB 31 | #endif 32 | { 33 | public static readonly string STORE = "appstore"; /**< AppStore name constant */ 34 | 35 | #if UNITY_IOS 36 | #region NativeMethods 37 | [DllImport("__Internal")] 38 | private static extern void AppStore_requestProducts(string[] skus, int skusNumber); 39 | 40 | [DllImport("__Internal")] 41 | private static extern void AppStore_startPurchase(string sku); 42 | 43 | [DllImport("__Internal")] 44 | private static extern void AppStore_restorePurchases(); 45 | 46 | [DllImport("__Internal")] 47 | private static extern bool Inventory_hasPurchase(string sku); 48 | 49 | [DllImport("__Internal")] 50 | private static extern void Inventory_query(); 51 | 52 | [DllImport("__Internal")] 53 | private static extern void Inventory_removePurchase(string sku); 54 | #endregion 55 | 56 | static Dictionary _sku2storeSkuMappings = new Dictionary(); 57 | static Dictionary _storeSku2skuMappings = new Dictionary(); 58 | 59 | private bool IsDevice() 60 | { 61 | if (Application.platform != RuntimePlatform.IPhonePlayer) 62 | { 63 | return false; 64 | } 65 | return true; 66 | } 67 | 68 | public void init(Options options) 69 | { 70 | if (!IsDevice()) return; 71 | init(options.storeKeys); 72 | } 73 | 74 | public void init(Dictionary storeKeys = null) 75 | { 76 | if (!IsDevice()) return; 77 | 78 | // Pass identifiers to the StoreKit 79 | string[] identifiers = new string[_sku2storeSkuMappings.Count]; 80 | for (int i = 0; i < _sku2storeSkuMappings.Count; ++i) 81 | { 82 | identifiers[i] = _sku2storeSkuMappings.ElementAt(i).Value; 83 | } 84 | 85 | AppStore_requestProducts(identifiers, identifiers.Length); 86 | } 87 | 88 | public void mapSku(string sku, string storeName, string storeSku) 89 | { 90 | if (storeName == STORE) 91 | { 92 | _sku2storeSkuMappings[sku] = storeSku; 93 | _storeSku2skuMappings[storeSku] = sku; 94 | } 95 | } 96 | 97 | public void unbindService() 98 | { 99 | } 100 | 101 | public bool areSubscriptionsSupported() 102 | { 103 | return true; 104 | } 105 | 106 | public void queryInventory() 107 | { 108 | if (!IsDevice()) 109 | { 110 | return; 111 | } 112 | Inventory_query(); 113 | } 114 | 115 | public void queryInventory(string[] skus) 116 | { 117 | queryInventory(); 118 | } 119 | 120 | public void purchaseProduct(string sku, string developerPayload = "") 121 | { 122 | string storeSku = _sku2storeSkuMappings[sku]; 123 | if (!IsDevice()) 124 | { 125 | // Fake purchase in editor mode 126 | OpenIAB.EventManager.SendMessage("OnPurchaseSucceeded", storeSku); 127 | return; 128 | } 129 | 130 | AppStore_startPurchase(storeSku); 131 | } 132 | 133 | public void purchaseSubscription(string sku, string developerPayload = "") 134 | { 135 | purchaseProduct(sku, developerPayload); 136 | } 137 | 138 | 139 | public void consumeProduct(Purchase purchase) 140 | { 141 | if (!IsDevice()) 142 | { 143 | // Fake consume in editor mode 144 | OpenIAB.EventManager.SendMessage("OnConsumePurchaseSucceeded", purchase.Serialize()); 145 | return; 146 | } 147 | 148 | var storeSku = OpenIAB_iOS.Sku2StoreSku(purchase.Sku); 149 | if (Inventory_hasPurchase(storeSku)) 150 | { 151 | OpenIAB.EventManager.SendMessage("OnConsumePurchaseSucceeded", purchase.Serialize()); 152 | Inventory_removePurchase(storeSku); 153 | } 154 | else 155 | { 156 | OpenIAB.EventManager.SendMessage("OnConsumePurchaseFailed", "Purchase not found"); 157 | } 158 | } 159 | 160 | public void restoreTransactions() 161 | { 162 | AppStore_restorePurchases(); 163 | } 164 | 165 | public bool isDebugLog() 166 | { 167 | return false; 168 | } 169 | 170 | public void enableDebugLogging(bool enabled) 171 | { 172 | } 173 | 174 | public void enableDebugLogging(bool enabled, string tag) 175 | { 176 | } 177 | 178 | public static string StoreSku2Sku(string storeSku) 179 | { 180 | return _storeSku2skuMappings[storeSku]; 181 | } 182 | 183 | public static string Sku2StoreSku(string sku) 184 | { 185 | return _sku2storeSkuMappings[sku]; 186 | } 187 | #endif 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB/iOS/OpenIAB_iOS.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0fdad166734e3840a72593c39a67638 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB_W8Plugin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/OpenIAB_W8Plugin.dll -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB_W8Plugin.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 19208cfdcc9245f48ad0e374142fdcc7 3 | timeCreated: 1427368186 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Android: 12 | enabled: 0 13 | settings: 14 | CPU: AnyCPU 15 | Any: 16 | enabled: 0 17 | settings: {} 18 | Editor: 19 | enabled: 1 20 | settings: 21 | CPU: AnyCPU 22 | DefaultValueInitialized: true 23 | OS: AnyOS 24 | Linux: 25 | enabled: 0 26 | settings: 27 | CPU: x86 28 | Linux64: 29 | enabled: 0 30 | settings: 31 | CPU: x86_64 32 | OSXIntel: 33 | enabled: 0 34 | settings: 35 | CPU: AnyCPU 36 | OSXIntel64: 37 | enabled: 0 38 | settings: 39 | CPU: AnyCPU 40 | WP8: 41 | enabled: 0 42 | settings: 43 | CPU: AnyCPU 44 | DontProcess: False 45 | PlaceholderPath: 46 | Win: 47 | enabled: 0 48 | settings: 49 | CPU: AnyCPU 50 | Win64: 51 | enabled: 0 52 | settings: 53 | CPU: AnyCPU 54 | WindowsStoreApps: 55 | enabled: 0 56 | settings: 57 | CPU: AnyCPU 58 | DontProcess: False 59 | PlaceholderPath: 60 | SDK: AnySDK 61 | iOS: 62 | enabled: 0 63 | settings: 64 | CompileFlags: 65 | FrameworkDependencies: 66 | userData: 67 | assetBundleName: 68 | assetBundleVariant: 69 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB_W8Plugin.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/OpenIAB_W8Plugin.pdb -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB_W8Plugin.pdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5289aa8a84ceb2042b8dffef999af3b3 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/OpenIAB_manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/OpenIAB_manual.pdf -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/WP8.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8ad0e7b80ac340d4d8b7c538ab468c73 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/WP8/OpenIAB_W8Plugin.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/WP8/OpenIAB_W8Plugin.dll -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/WP8/OpenIAB_W8Plugin.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 45d85ee3d64e8ef4ea1e6163010d8f9f 3 | timeCreated: 1427368189 4 | licenseType: Free 5 | PluginImporter: 6 | serializedVersion: 1 7 | iconMap: {} 8 | executionOrder: {} 9 | isPreloaded: 0 10 | platformData: 11 | Android: 12 | enabled: 0 13 | settings: 14 | CPU: AnyCPU 15 | Any: 16 | enabled: 0 17 | settings: {} 18 | Editor: 19 | enabled: 0 20 | settings: 21 | CPU: AnyCPU 22 | DefaultValueInitialized: true 23 | OS: AnyOS 24 | Linux: 25 | enabled: 0 26 | settings: 27 | CPU: x86 28 | Linux64: 29 | enabled: 0 30 | settings: 31 | CPU: x86_64 32 | OSXIntel: 33 | enabled: 0 34 | settings: 35 | CPU: AnyCPU 36 | OSXIntel64: 37 | enabled: 0 38 | settings: 39 | CPU: AnyCPU 40 | WP8: 41 | enabled: 1 42 | settings: 43 | CPU: AnyCPU 44 | DontProcess: False 45 | PlaceholderPath: Assets/Plugins/OpenIAB_W8Plugin.dll 46 | Win: 47 | enabled: 0 48 | settings: 49 | CPU: AnyCPU 50 | Win64: 51 | enabled: 0 52 | settings: 53 | CPU: AnyCPU 54 | WindowsStoreApps: 55 | enabled: 0 56 | settings: 57 | CPU: AnyCPU 58 | DontProcess: False 59 | PlaceholderPath: 60 | SDK: AnySDK 61 | iOS: 62 | enabled: 0 63 | settings: 64 | CompileFlags: 65 | FrameworkDependencies: 66 | userData: 67 | assetBundleName: 68 | assetBundleVariant: 69 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/WP8/OpenIAB_W8Plugin.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onepf/OpenIAB-Unity-Plugin/19b1719190dbac24c9240db7e83be820b40a93e5/unity_plugin/unity_src/Assets/Plugins/WP8/OpenIAB_W8Plugin.pdb -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/WP8/OpenIAB_W8Plugin.pdb.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a913e4607797054d87da031eb3f7216 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 00580a8394cbe88489dc735dabae3b61 3 | DefaultImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS/AppStoreBridge.mm: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #import "AppStoreDelegate.h" 18 | 19 | /** 20 | * Unity to NS String conversion 21 | * @param c_string original C string 22 | */ 23 | NSString* ToString(const char* c_string) 24 | { 25 | return c_string == NULL ? [NSString stringWithUTF8String:""] : [NSString stringWithUTF8String:c_string]; 26 | } 27 | 28 | extern "C" 29 | { 30 | /** 31 | * Native 'requestProducts' wrapper 32 | * @param skus product IDs 33 | * @param skuNumber lenght of the 'skus' array 34 | */ 35 | void AppStore_requestProducts(const char* skus[], int skuNumber) 36 | { 37 | NSMutableSet *skuSet = [NSMutableSet set]; 38 | for (int i = 0; i < skuNumber; ++i) 39 | [skuSet addObject: ToString(skus[i])]; 40 | [[AppStoreDelegate instance] requestSKUs:skuSet]; 41 | } 42 | 43 | /** 44 | * Native 'startPurchase' wrapper 45 | * @param sku product ID 46 | */ 47 | void AppStore_startPurchase(const char* sku) 48 | { 49 | [[AppStoreDelegate instance] startPurchase:ToString(sku)]; 50 | } 51 | 52 | /** 53 | * Native 'restorePurchases' wrapper 54 | */ 55 | void AppStore_restorePurchases() 56 | { 57 | [[AppStoreDelegate instance] restorePurchases]; 58 | } 59 | 60 | /** 61 | * Query inventory 62 | * Restore purchased items 63 | */ 64 | void Inventory_query() 65 | { 66 | [[AppStoreDelegate instance] queryInventory]; 67 | } 68 | 69 | /** 70 | * Checks if product is purchased 71 | * @param sku product ID 72 | * @return true if product was purchased 73 | */ 74 | bool Inventory_hasPurchase(const char* sku) 75 | { 76 | NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; 77 | if (standardUserDefaults) 78 | { 79 | return [[[standardUserDefaults dictionaryRepresentation] allKeys] containsObject:ToString(sku)]; 80 | } 81 | else 82 | { 83 | NSLog(@"Couldn't access purchase storage."); 84 | return false; 85 | } 86 | } 87 | 88 | /** 89 | * Delete purchase information 90 | * @param sku product ID 91 | */ 92 | void Inventory_removePurchase(const char* sku) 93 | { 94 | NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; 95 | if (standardUserDefaults) 96 | { 97 | [standardUserDefaults removeObjectForKey:ToString(sku)]; 98 | [standardUserDefaults synchronize]; 99 | } 100 | else 101 | { 102 | NSLog(@"Couldn't access standardUserDefaults. Purchase wasn't removed."); 103 | } 104 | } 105 | } -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS/AppStoreBridge.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 648bd03bf6f1b4b81b502a1555ba7f81 3 | PluginImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | isPreloaded: 0 8 | platformData: 9 | Any: 10 | enabled: 0 11 | settings: {} 12 | Editor: 13 | enabled: 0 14 | settings: 15 | DefaultValueInitialized: true 16 | iOS: 17 | enabled: 1 18 | settings: {} 19 | userData: 20 | assetBundleName: 21 | assetBundleVariant: 22 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS/AppStoreDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppStoreDelegate : NSObject 5 | 6 | /** 7 | * Get instance of the StoreKit delegate 8 | * @return instance of the StoreKit delegate 9 | */ 10 | + (AppStoreDelegate*)instance; 11 | 12 | /** 13 | * Request sku listing from the AppStore 14 | * @param skus product IDs 15 | */ 16 | - (void)requestSKUs:(NSSet*)skus; 17 | 18 | /** 19 | * Start async purchase process 20 | * @param product ID 21 | */ 22 | - (void)startPurchase:(NSString*)sku; 23 | 24 | /** 25 | * Request purchase history 26 | */ 27 | - (void)queryInventory; 28 | 29 | /** 30 | * This is required by AppStore. 31 | * Separate button for restoration should be added somewhere in the application 32 | */ 33 | - (void)restorePurchases; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS/AppStoreDelegate.h.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 07bcd18476ebd478fbcf92354a77684c 3 | PluginImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | isPreloaded: 0 8 | platformData: 9 | Any: 10 | enabled: 0 11 | settings: {} 12 | Editor: 13 | enabled: 0 14 | settings: 15 | DefaultValueInitialized: true 16 | iOS: 17 | enabled: 1 18 | settings: {} 19 | userData: 20 | assetBundleName: 21 | assetBundleVariant: 22 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS/AppStoreDelegate.mm: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | #import "AppStoreDelegate.h" 18 | #import 19 | 20 | /** 21 | * Helper method to create C string copy 22 | * By default mono string marshaler creates .Net string for returned UTF-8 C string 23 | * and calls free for returned value, thus returned strings should be allocated on heap 24 | * @param string original C string 25 | */ 26 | char* MakeStringCopy(const char* string) 27 | { 28 | if (string == NULL) 29 | return NULL; 30 | 31 | char* res = (char*)malloc(strlen(string) + 1); 32 | strcpy(res, string); 33 | return res; 34 | } 35 | 36 | /** 37 | * It is used to send callbacks to the Unity event handler 38 | * @param objectName name of the target GameObject 39 | * @param methodName name of the handler method 40 | * @param param message string 41 | */ 42 | extern void UnitySendMessage(const char* objectName, const char* methodName, const char* param); 43 | 44 | /** 45 | * Name of the event handler object in Unity 46 | */ 47 | const char* EventHandler = "OpenIABEventManager"; 48 | 49 | @implementation AppStoreDelegate 50 | 51 | // Internal 52 | 53 | /** 54 | * Collection of product identifiers 55 | */ 56 | NSSet* m_skus; 57 | 58 | /** 59 | * Map of product listings 60 | * Information is requested from the store 61 | */ 62 | NSMutableArray* m_skuMap; 63 | 64 | /** 65 | * Dictionary {sku: product} 66 | */ 67 | NSMutableDictionary* m_productMap; 68 | 69 | 70 | - (void)storePurchase:(NSString*)transaction forSku:(NSString*)sku 71 | { 72 | NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults]; 73 | if (standardUserDefaults) 74 | { 75 | [standardUserDefaults setObject:transaction forKey:sku]; 76 | [standardUserDefaults synchronize]; 77 | } 78 | else 79 | NSLog(@"Couldn't access standardUserDefaults. Purchase wasn't stored."); 80 | } 81 | 82 | 83 | // Init 84 | 85 | + (AppStoreDelegate*)instance 86 | { 87 | static AppStoreDelegate* instance = nil; 88 | if (!instance) 89 | instance = [[AppStoreDelegate alloc] init]; 90 | 91 | return instance; 92 | } 93 | 94 | - (id)init 95 | { 96 | self = [super init]; 97 | [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 98 | return self; 99 | } 100 | 101 | - (void)dealloc 102 | { 103 | [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; 104 | m_skus = nil; 105 | m_skuMap = nil; 106 | m_productMap = nil; 107 | } 108 | 109 | 110 | // Setup 111 | 112 | - (void)requestSKUs:(NSSet*)skus 113 | { 114 | m_skus = skus; 115 | SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:skus]; 116 | request.delegate = self; 117 | [request start]; 118 | } 119 | 120 | // Setup handler 121 | 122 | - (void)productsRequest:(SKProductsRequest*)request didReceiveResponse:(SKProductsResponse*)response 123 | { 124 | m_skuMap = [[NSMutableArray alloc] init]; 125 | m_productMap = [[NSMutableDictionary alloc] init]; 126 | 127 | NSArray* skProducts = response.products; 128 | for (SKProduct * skProduct in skProducts) 129 | { 130 | // Format the price 131 | NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 132 | [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; 133 | [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; 134 | [numberFormatter setLocale:skProduct.priceLocale]; 135 | NSString *formattedPrice = [numberFormatter stringFromNumber:skProduct.price]; 136 | 137 | NSLocale *priceLocale = skProduct.priceLocale; 138 | NSString *currencyCode = [priceLocale objectForKey:NSLocaleCurrencyCode]; 139 | NSNumber *productPrice = skProduct.price; 140 | 141 | // Setup sku details 142 | NSDictionary* skuDetails = [NSDictionary dictionaryWithObjectsAndKeys: 143 | @"product", @"itemType", 144 | skProduct.productIdentifier, @"sku", 145 | @"product", @"type", 146 | formattedPrice, @"price", 147 | currencyCode, @"currencyCode", 148 | productPrice, @"priceValue", 149 | ([skProduct.localizedTitle length] == 0) ? @"" : skProduct.localizedTitle, @"title", 150 | ([skProduct.localizedDescription length] == 0) ? @"" : skProduct.localizedDescription, @"description", 151 | @"", @"json", 152 | nil]; 153 | 154 | NSArray* entry = [NSArray arrayWithObjects:skProduct.productIdentifier, skuDetails, nil]; 155 | [m_skuMap addObject:entry]; 156 | [m_productMap setObject:skProduct forKey:skProduct.productIdentifier]; 157 | } 158 | 159 | UnitySendMessage(EventHandler, "OnBillingSupported", MakeStringCopy("")); 160 | } 161 | 162 | - (void)request:(SKRequest*)request didFailWithError:(NSError*)error 163 | { 164 | UnitySendMessage(EventHandler, "OnBillingNotSupported", MakeStringCopy([[error localizedDescription] UTF8String])); 165 | } 166 | 167 | 168 | // Transactions 169 | 170 | - (void)startPurchase:(NSString*)sku 171 | { 172 | SKProduct* product = m_productMap[sku]; 173 | SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product]; 174 | [[SKPaymentQueue defaultQueue] addPayment:payment]; 175 | } 176 | 177 | - (void)queryInventory 178 | { 179 | NSMutableDictionary* inventory = [[NSMutableDictionary alloc] init]; 180 | NSMutableArray* purchaseMap = [[NSMutableArray alloc] init]; 181 | NSUserDefaults* standardUserDefaults = [NSUserDefaults standardUserDefaults]; 182 | if (!standardUserDefaults) 183 | NSLog(@"Couldn't access purchase storage. Purchase map won't be available."); 184 | else 185 | for (NSString* sku in m_skus) 186 | if ([[[standardUserDefaults dictionaryRepresentation] allKeys] containsObject:sku]) 187 | { 188 | NSString* encodedPurchase = [standardUserDefaults objectForKey:sku]; 189 | NSError *e = nil; 190 | NSDictionary* storedPurchase = [NSJSONSerialization JSONObjectWithData: 191 | [encodedPurchase dataUsingEncoding:NSUTF8StringEncoding] 192 | options: NSJSONReadingMutableContainers error: &e]; 193 | if (!storedPurchase) { 194 | NSLog(@"Got an error while creating the JSON object: %@", e); 195 | continue; 196 | } 197 | 198 | // TODO: Probably store all purchase information. Not only sku 199 | // Setup purchase 200 | NSDictionary* purchase = [NSDictionary dictionaryWithObjectsAndKeys: 201 | @"product", @"itemType", 202 | [storedPurchase objectForKey:@"orderId"], @"orderId", 203 | [storedPurchase objectForKey:@"receipt"], @"receipt", 204 | @"", @"packageName", 205 | sku, @"sku", 206 | [NSNumber numberWithLong:0], @"purchaseTime", 207 | // TODO: copy constants from Android if ever needed 208 | [NSNumber numberWithInt:0], @"purchaseState", 209 | @"", @"developerPayload", 210 | @"", @"token", 211 | @"", @"originalJson", 212 | @"", @"signature", 213 | @"", @"appstoreName", 214 | nil]; 215 | 216 | NSArray* entry = [NSArray arrayWithObjects:sku, purchase, nil]; 217 | [purchaseMap addObject:entry]; 218 | } 219 | 220 | [inventory setObject:purchaseMap forKey:@"purchaseMap"]; 221 | [inventory setObject:m_skuMap forKey:@"skuMap"]; 222 | 223 | NSError* error = nil; 224 | NSData* jsonData = [NSJSONSerialization dataWithJSONObject:inventory options:kNilOptions error:&error]; 225 | NSString* message = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; 226 | UnitySendMessage(EventHandler, "OnQueryInventorySucceeded", MakeStringCopy([message UTF8String])); 227 | } 228 | 229 | - (void)restorePurchases 230 | { 231 | [[SKPaymentQueue defaultQueue] restoreCompletedTransactions]; 232 | } 233 | 234 | 235 | // Transactions handler 236 | 237 | - (void)paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray *)downloads 238 | { 239 | // Required by store protocol 240 | } 241 | 242 | - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions 243 | { 244 | NSString* jsonTransaction; 245 | 246 | for (SKPaymentTransaction *transaction in transactions) 247 | { 248 | switch (transaction.transactionState) 249 | { 250 | case SKPaymentTransactionStatePurchasing: 251 | case SKPaymentTransactionStateDeferred: 252 | break; 253 | 254 | case SKPaymentTransactionStateFailed: 255 | if (transaction.error == nil) 256 | UnitySendMessage(EventHandler, "OnPurchaseFailed", MakeStringCopy("Transaction failed")); 257 | else if (transaction.error.code == SKErrorPaymentCancelled) 258 | UnitySendMessage(EventHandler, "OnPurchaseFailed", MakeStringCopy("Transaction cancelled")); 259 | else 260 | UnitySendMessage(EventHandler, "OnPurchaseFailed", MakeStringCopy([[transaction.error localizedDescription] UTF8String])); 261 | [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 262 | break; 263 | 264 | case SKPaymentTransactionStateRestored: 265 | jsonTransaction = [self convertTransactionToJson:transaction.originalTransaction storeToUserDefaults:true]; 266 | if ([jsonTransaction isEqual: @"error"]) 267 | { 268 | return; 269 | } 270 | 271 | UnitySendMessage(EventHandler, "OnPurchaseRestored", MakeStringCopy([jsonTransaction UTF8String])); 272 | [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 273 | break; 274 | 275 | case SKPaymentTransactionStatePurchased: 276 | jsonTransaction = [self convertTransactionToJson:transaction storeToUserDefaults:true]; 277 | if ([jsonTransaction isEqual: @"error"]) 278 | { 279 | return; 280 | } 281 | 282 | UnitySendMessage(EventHandler, "OnPurchaseSucceeded", MakeStringCopy([jsonTransaction UTF8String])); 283 | [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 284 | break; 285 | } 286 | } 287 | } 288 | 289 | - (NSString*)convertTransactionToJson: (SKPaymentTransaction*) transaction storeToUserDefaults:(bool)store 290 | { 291 | //NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 292 | //NSData *receipt = [NSData dataWithContentsOfURL:receiptURL]; 293 | //NSString *receiptBase64 = [receipt base64EncodedStringWithOptions:0]; 294 | 295 | NSString *receiptBase64 = [transaction.transactionReceipt base64EncodedStringWithOptions:0]; 296 | 297 | NSDictionary *requestContents = [NSDictionary dictionaryWithObjectsAndKeys: 298 | transaction.payment.productIdentifier, @"sku", 299 | transaction.transactionIdentifier, @"orderId", 300 | receiptBase64, @"receipt", 301 | nil]; 302 | 303 | NSError *error; 304 | NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents 305 | options:0 306 | error:&error]; 307 | if (!requestData) { 308 | NSLog(@"Got an error while creating the JSON object: %@", error); 309 | return @"error"; 310 | } 311 | 312 | NSString * jsonString = [[NSString alloc] initWithData:requestData encoding:NSUTF8StringEncoding]; 313 | 314 | if (store){ 315 | [self storePurchase:jsonString 316 | forSku:transaction.payment.productIdentifier 317 | ]; 318 | } 319 | 320 | return jsonString; 321 | } 322 | 323 | - (void)paymentQueue:(SKPaymentQueue*)queue restoreCompletedTransactionsFailedWithError:(NSError*)error 324 | { 325 | UnitySendMessage(EventHandler, "OnRestoreFailed", MakeStringCopy([[error localizedDescription] UTF8String])); 326 | } 327 | 328 | - (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue*)queue 329 | { 330 | UnitySendMessage(EventHandler, "OnRestoreFinished", MakeStringCopy("")); 331 | } 332 | 333 | @end 334 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/Assets/Plugins/iOS/AppStoreDelegate.mm.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 3a4dadbd5b5d1431a8a972257a83d498 3 | PluginImporter: 4 | serializedVersion: 1 5 | iconMap: {} 6 | executionOrder: {} 7 | isPreloaded: 0 8 | platformData: 9 | Any: 10 | enabled: 0 11 | settings: {} 12 | Editor: 13 | enabled: 0 14 | settings: 15 | DefaultValueInitialized: true 16 | iOS: 17 | enabled: 1 18 | settings: {} 19 | userData: 20 | assetBundleName: 21 | assetBundleVariant: 22 | -------------------------------------------------------------------------------- /unity_plugin/unity_src/unity_src.userprefs: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/EditorDLL/EditorDLL.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {97A377FA-5E62-4995-814B-F32EB417434A} 8 | Library 9 | Properties 10 | OpenIAB_W8Plugin 11 | OpenIAB_W8Plugin 12 | v3.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | ..\..\unity_src\Assets\Plugins\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | ..\..\unity_src\Assets\Plugins\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 45 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/EditorDLL/ProductListing.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | namespace OnePF.WP8 18 | { 19 | // Summary: 20 | // Provides localized info about an in-app offer in your app. 21 | public sealed class ProductListing 22 | { 23 | public ProductListing( 24 | string productId, 25 | string name, 26 | string description, 27 | string formattedPrice) 28 | { 29 | ProductId = productId; 30 | Name = name; 31 | Description = description; 32 | FormattedPrice = formattedPrice; 33 | } 34 | 35 | // Summary: 36 | // Gets the description for the product. 37 | // 38 | // Returns: 39 | // The description for the product. 40 | public string Description { get; private set; } 41 | // 42 | // Summary: 43 | // Gets the app's purchase price with the appropriate formatting for the current 44 | // market. 45 | // 46 | // Returns: 47 | // The app's purchase price with the appropriate formatting for the current 48 | // market. 49 | public string FormattedPrice { get; private set; } 50 | // 51 | // Summary: 52 | // Gets the descriptive name of the product or feature that can be shown to 53 | // customers in the current market. 54 | // 55 | // Returns: 56 | // The feature's descriptive name as it is seen by customers in the current 57 | // market. 58 | public string Name { get; private set; } 59 | // 60 | // Summary: 61 | // Gets the ID of an app's feature or product. 62 | // 63 | // Returns: 64 | // The ID of an app's feature. 65 | public string ProductId { get; private set; } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/EditorDLL/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Resources; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("OpenIAB_W8Plugin")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("OnePF")] 13 | [assembly: AssemblyProduct("OpenIAB_W8Plugin")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("e119f8a2-9eca-4fa7-a6a8-17579045c727")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("1.0.0.0")] 37 | [assembly: AssemblyFileVersion("1.0.0.0")] 38 | [assembly: NeutralResourcesLanguageAttribute("")] 39 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/EditorDLL/Store.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using System.Collections.Generic; 18 | using System; 19 | 20 | namespace OnePF.WP8 21 | { 22 | public class Store 23 | { 24 | public static event Action> LoadListingsSucceeded; 25 | public static event Action LoadListingsFailed; 26 | public static event Action PurchaseSucceeded; 27 | public static event Action PurchaseFailed; 28 | public static event Action ConsumeSucceeded; 29 | public static event Action ConsumeFailed; 30 | 31 | public static IEnumerable Inventory { get { return new List(); } } 32 | 33 | public static void LoadListings(string[] productIds) 34 | { 35 | if (LoadListingsSucceeded != null) 36 | LoadListingsSucceeded(new Dictionary()); 37 | } 38 | 39 | public static void PurchaseProduct(string productId, string developerPayload) 40 | { 41 | if (PurchaseSucceeded != null) 42 | PurchaseSucceeded(productId, developerPayload); 43 | } 44 | 45 | public static void ConsumeProduct(string productId) 46 | { 47 | if (ConsumeSucceeded != null) 48 | ConsumeSucceeded(productId); 49 | } 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/RealDLL/HResult.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | namespace OnePF.WP8 18 | { 19 | public enum HResult : uint 20 | { 21 | S_OK = 0x00000000, 22 | E_FAIL = 0x80004005, 23 | E_UNEXPECTED = 0x8000FFFF, 24 | E_404 = 0x805A0194 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/RealDLL/ProductListing.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | namespace OnePF.WP8 18 | { 19 | // Summary: 20 | // Provides localized info about an in-app offer in your app. 21 | public sealed class ProductListing 22 | { 23 | public ProductListing( 24 | string productId, 25 | string name, 26 | string description, 27 | string formattedPrice) 28 | { 29 | ProductId = productId; 30 | Name = name; 31 | Description = description; 32 | FormattedPrice = formattedPrice; 33 | } 34 | 35 | // Summary: 36 | // Gets the description for the product. 37 | // 38 | // Returns: 39 | // The description for the product. 40 | public string Description { get; private set; } 41 | // 42 | // Summary: 43 | // Gets the app's purchase price with the appropriate formatting for the current 44 | // market. 45 | // 46 | // Returns: 47 | // The app's purchase price with the appropriate formatting for the current 48 | // market. 49 | public string FormattedPrice { get; private set; } 50 | // 51 | // Summary: 52 | // Gets the descriptive name of the product or feature that can be shown to 53 | // customers in the current market. 54 | // 55 | // Returns: 56 | // The feature's descriptive name as it is seen by customers in the current 57 | // market. 58 | public string Name { get; private set; } 59 | // 60 | // Summary: 61 | // Gets the ID of an app's feature or product. 62 | // 63 | // Returns: 64 | // The ID of an app's feature. 65 | public string ProductId { get; private set; } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/RealDLL/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | using System.Resources; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("OpenIAB_W8Plugin")] 10 | [assembly: AssemblyDescription("")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("OnePF")] 13 | [assembly: AssemblyProduct("OpenIAB_W8Plugin")] 14 | [assembly: AssemblyCopyright("Copyright © 2014")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("b1ea264e-c60a-4e58-af77-cc7c20c0678e")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Revision and Build Numbers 34 | // by using the '*' as shown below: 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | [assembly: NeutralResourcesLanguageAttribute("en-US")] 38 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/RealDLL/RealDLL.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 10.0.20506 7 | 2.0 8 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E} 9 | {C089C8C0-30E0-4E22-80C0-CE093F111A43};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 10 | Library 11 | Properties 12 | OpenIAB_W8Plugin 13 | OpenIAB_W8Plugin 14 | WindowsPhone 15 | v8.0 16 | $(TargetFrameworkVersion) 17 | false 18 | true 19 | 11.0 20 | true 21 | 22 | 23 | true 24 | full 25 | false 26 | ..\..\unity_src\Assets\Plugins\WP8\ 27 | DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE 28 | true 29 | true 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | pdbonly 37 | true 38 | ..\..\unity_src\Assets\Plugins\WP8\ 39 | TRACE;SILVERLIGHT;WINDOWS_PHONE 40 | true 41 | true 42 | prompt 43 | 4 44 | 45 | 46 | true 47 | full 48 | false 49 | Bin\x86\Debug 50 | DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE 51 | true 52 | true 53 | prompt 54 | 4 55 | 56 | 57 | pdbonly 58 | true 59 | Bin\x86\Release 60 | TRACE;SILVERLIGHT;WINDOWS_PHONE 61 | true 62 | true 63 | prompt 64 | 4 65 | 66 | 67 | true 68 | full 69 | false 70 | Bin\ARM\Debug 71 | DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE 72 | true 73 | true 74 | prompt 75 | 4 76 | 77 | 78 | pdbonly 79 | true 80 | Bin\ARM\Release 81 | TRACE;SILVERLIGHT;WINDOWS_PHONE 82 | true 83 | true 84 | prompt 85 | 4 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 103 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/RealDLL/Store.cs: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2012-2014 One Platform Foundation 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | ******************************************************************************/ 16 | 17 | using System; 18 | using Windows.ApplicationModel.Store; 19 | using System.Collections.Generic; 20 | using System.Linq; 21 | using System.Threading.Tasks; 22 | using Windows.Foundation; 23 | using System.Windows.Threading; 24 | using System.Windows; 25 | 26 | namespace OnePF.WP8 27 | { 28 | public class Store 29 | { 30 | public static event Action> LoadListingsSucceeded; 31 | public static event Action LoadListingsFailed; 32 | public static event Action PurchaseSucceeded; 33 | public static event Action PurchaseFailed; 34 | public static event Action ConsumeSucceeded; 35 | public static event Action ConsumeFailed; 36 | 37 | static string GetErrorDescription(Exception exception) 38 | { 39 | string errorMessage; 40 | switch ((HResult) exception.HResult) 41 | { 42 | case HResult.E_FAIL: 43 | errorMessage = "Purchase cancelled"; 44 | break; 45 | case HResult.E_404: 46 | errorMessage = "Not found"; 47 | break; 48 | default: 49 | errorMessage = exception.Message; 50 | break; 51 | } 52 | return errorMessage; 53 | } 54 | 55 | public static IEnumerable Inventory 56 | { 57 | get 58 | { 59 | List productLicensesList = new List(); 60 | IReadOnlyDictionary productLicenses = CurrentApp.LicenseInformation.ProductLicenses; 61 | if (productLicenses != null) 62 | foreach (var pl in productLicenses.Values) 63 | if (pl.IsActive) 64 | productLicensesList.Add(pl.ProductId); 65 | return productLicensesList; 66 | } 67 | } 68 | 69 | public static void LoadListings(string[] productIds) 70 | { 71 | Deployment.Current.Dispatcher.BeginInvoke(() => 72 | { 73 | Dictionary resultListings = new Dictionary(); 74 | IAsyncOperation asyncOp; 75 | try 76 | { 77 | asyncOp = CurrentApp.LoadListingInformationByProductIdsAsync(productIds); 78 | } 79 | catch(Exception e) 80 | { 81 | if (LoadListingsFailed != null) 82 | LoadListingsFailed(GetErrorDescription(e)); 83 | return; 84 | } 85 | 86 | asyncOp.Completed = (op, status) => 87 | { 88 | if (op.Status == AsyncStatus.Error) 89 | { 90 | if (LoadListingsFailed != null) 91 | LoadListingsFailed(GetErrorDescription(op.ErrorCode)); 92 | return; 93 | } 94 | 95 | if (op.Status == AsyncStatus.Canceled) 96 | { 97 | if (LoadListingsFailed != null) 98 | LoadListingsFailed("QueryInventory was cancelled"); 99 | return; 100 | } 101 | 102 | var listings = op.GetResults(); 103 | foreach (var l in listings.ProductListings) 104 | { 105 | var listing = l.Value; 106 | var resultListing = new ProductListing( 107 | listing.ProductId, 108 | listing.Name, 109 | listing.Description, 110 | listing.FormattedPrice); 111 | resultListings[l.Key] = resultListing; 112 | } 113 | if (LoadListingsSucceeded != null) 114 | LoadListingsSucceeded(resultListings); 115 | }; 116 | }); 117 | } 118 | 119 | public static void PurchaseProduct(string productId, string developerPayload) 120 | { 121 | Deployment.Current.Dispatcher.BeginInvoke(() => 122 | { 123 | // Kick off purchase; don't ask for a receipt when it returns 124 | IAsyncOperation asyncOp; 125 | try 126 | { 127 | asyncOp = CurrentApp.RequestProductPurchaseAsync(productId, false); 128 | } 129 | catch (Exception e) 130 | { 131 | if (PurchaseFailed != null) 132 | PurchaseFailed(GetErrorDescription(e)); 133 | return; 134 | } 135 | 136 | asyncOp.Completed = (op, status) => 137 | { 138 | if (op.Status == AsyncStatus.Error) 139 | { 140 | if (PurchaseFailed != null) 141 | PurchaseFailed(GetErrorDescription(op.ErrorCode)); 142 | return; 143 | } 144 | 145 | if (op.Status == AsyncStatus.Canceled) 146 | { 147 | if (PurchaseFailed != null) 148 | PurchaseFailed("Purchase was cancelled"); 149 | return; 150 | } 151 | 152 | string errorMessage; 153 | ProductLicense productLicense = null; 154 | if (CurrentApp.LicenseInformation.ProductLicenses.TryGetValue(productId, out productLicense)) 155 | { 156 | if (productLicense.IsActive) 157 | { 158 | if (PurchaseSucceeded != null) 159 | PurchaseSucceeded(productId, developerPayload); 160 | return; 161 | } 162 | else 163 | { 164 | errorMessage = op.ErrorCode.Message; 165 | } 166 | } 167 | else 168 | { 169 | errorMessage = op.ErrorCode.Message; 170 | } 171 | 172 | if (PurchaseFailed != null) 173 | PurchaseFailed(errorMessage); 174 | }; 175 | }); 176 | } 177 | 178 | public static void ConsumeProduct(string productId) 179 | { 180 | Deployment.Current.Dispatcher.BeginInvoke(() => 181 | { 182 | try 183 | { 184 | CurrentApp.ReportProductFulfillment(productId); 185 | } 186 | catch (Exception e) 187 | { 188 | if (ConsumeFailed != null) 189 | ConsumeFailed(e.Message); 190 | return; 191 | } 192 | if (ConsumeSucceeded != null) 193 | ConsumeSucceeded(productId); 194 | }); 195 | } 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /unity_plugin/wp8_dll_src/UnityW8Plugin.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RealDLL", "RealDLL\RealDLL.csproj", "{B1EA264E-C60A-4E58-AF77-CC7C20C0678E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EditorDLL", "EditorDLL\EditorDLL.csproj", "{97A377FA-5E62-4995-814B-F32EB417434A}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|ARM = Debug|ARM 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|ARM = Release|ARM 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Debug|ARM.ActiveCfg = Debug|ARM 23 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Debug|ARM.Build.0 = Debug|ARM 24 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Debug|x86.ActiveCfg = Debug|x86 25 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Debug|x86.Build.0 = Debug|x86 26 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Release|ARM.ActiveCfg = Release|ARM 29 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Release|ARM.Build.0 = Release|ARM 30 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Release|x86.ActiveCfg = Release|x86 31 | {B1EA264E-C60A-4E58-AF77-CC7C20C0678E}.Release|x86.Build.0 = Release|x86 32 | {97A377FA-5E62-4995-814B-F32EB417434A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {97A377FA-5E62-4995-814B-F32EB417434A}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {97A377FA-5E62-4995-814B-F32EB417434A}.Debug|ARM.ActiveCfg = Debug|Any CPU 35 | {97A377FA-5E62-4995-814B-F32EB417434A}.Debug|x86.ActiveCfg = Debug|Any CPU 36 | {97A377FA-5E62-4995-814B-F32EB417434A}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {97A377FA-5E62-4995-814B-F32EB417434A}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {97A377FA-5E62-4995-814B-F32EB417434A}.Release|ARM.ActiveCfg = Release|Any CPU 39 | {97A377FA-5E62-4995-814B-F32EB417434A}.Release|x86.ActiveCfg = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | EndGlobal 45 | --------------------------------------------------------------------------------