Skip to content

Commit

Permalink
Merge pull request #65 from j3k0/rb3.9
Browse files Browse the repository at this point in the history
Release 3.9
  • Loading branch information
j3k0 committed Nov 29, 2014
2 parents 63eb07e + fc723fe commit c6d0474
Show file tree
Hide file tree
Showing 53 changed files with 1,306 additions and 806 deletions.
18 changes: 18 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"env" : {
"node" : true,
"browser" : true
},
"rules" : {
"strict": 1,
"quotes": 0,
"no-underscore-dangle": 0,
"no-multi-spaces": 0,
"key-spacing": 0,
"curly": 0,
"no-use-before-define": [ 1, "nofunc" ]
},
"globals" : {
"store": true
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
/node_modules/
/coverage/
/test/tmp/
/www/.store-android.js
/www/.store-ios.js
*~
9 changes: 9 additions & 0 deletions .jshintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"node": true,
"browser": true,
"undef": true,
"globals": {
"store": true,
"cordova": true
}
}
17 changes: 11 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ build: sync-android test-js
@echo "- Preprocess"
@node_modules/.bin/preprocess src/js/store-ios.js src/js | node_modules/.bin/uglifyjs -b > www/store-ios.js
@node_modules/.bin/preprocess src/js/store-android.js src/js | node_modules/.bin/uglifyjs -b > www/store-android.js
@echo "- DONE"
@echo "- Done"
@echo ""

prepare-test-js:
Expand All @@ -33,15 +33,20 @@ prepare-test-js:
@cp src/js/platforms/*-adapter.js test/tmp/
@#node_modules/.bin/istanbul instrument --no-compact --output test/tmp/store-test.js test/store-test-src.js

jshint: check-jshint
jshint: check-jshint sync-android
@echo "- JSHint"
@node_modules/.bin/jshint src/js/*.js test/js/*.js
@node_modules/.bin/jshint --config .jshintrc src/js/*.js src/js/platforms/*.js test/js/*.js

test-js: jshint prepare-test-js
eslint: jshint
@echo "- ESLint"
@node_modules/.bin/eslint --config .eslintrc src/js/*.js src/js/platforms/*.js test/js/*.js

test-js: jshint eslint prepare-test-js
@echo "- Mocha"
@node_modules/.bin/istanbul test --root test/tmp test/js/run.js
@echo

test-js-coverage: jshint prepare-test-js
test-js-coverage: jshint eslint prepare-test-js
@echo "- Mocha / Instanbul"
@node_modules/.bin/istanbul cover --root test/ test/js/run.js
@node_modules/.bin/coveralls < coverage/lcov.info
Expand All @@ -67,7 +72,7 @@ doc-contrib: test-js
@echo >> doc/contributor-guide.md
@echo "*(generated from source files using \`make doc-contrib)\`*" >> doc/contributor-guide.md
@echo >> doc/contributor-guide.md
@cat src/js/*.js | grep "//!" | cut -d! -f2- | cut -d\ -f2- >> doc/contributor-guide.md
@cat src/js/*.js src/js/platforms/*.js | grep "//!" | cut -d! -f2- | cut -d\ -f2- >> doc/contributor-guide.md

doc: doc-api doc-contrib

Expand Down
39 changes: 2 additions & 37 deletions doc/android.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,3 @@
# Setup

## Add your license key

As android uses a public key for verification of purchase data consistency, you have to put the public key of your application inside the config.xml file under a preference tag like this:

<preference name="android-iabplugin-license-key" value="yourpublickey" />

You can find your public key inside Google Developer Console under SERVICES & APIS tab of the specific application.

## PlayStore

from https://github.com/mohamnag/InAppBilling/wiki/Stores%20setup#playstore

> Recently you can test IAP on PlayStore only if your app is already published. If you don't want to make it available before testing, you can publish it in alpha (recommended) or beta state instead of production.
Read Google's documentations about IAP and testing it. Any thing may have been changed in between.

Steps to setup IAP in Google's developer console:

1. `Developer Console` Create your app, provide all needed meta data

2. `Developer Console` Upload a **signed release** APK to either alpha, beta or production

3. `Developer Console` Setup your in app items

4. `Developer Console` Setup your test users if you don't want to spend real money buying your own app ;)
Its easier to be done with an alpha published app. You add users to a google group then send a link and they sign up on their own.

4. `Developer Console` Publish your app and wait until it is available to (test) users.
This may take hours!

5. Install **same** release signed app on a device which is logged into play store using a test account.
If you use the debug build, you can do some actions, however you will not be able to buy the product.

6. Try in-app purchasing!

This have moved:

See https://github.com/j3k0/cordova-plugin-purchase/wiki/HOWTO#setup-android-applications
18 changes: 9 additions & 9 deletions doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ be contacted to load informations about the registered products: human
readable `title` and `description`, `price`, etc.

This isn't an optional step as some despotic store owners (like Apple) require you
to display information about a product as retrieved from their server: no
to display information about a product as retrieved from their server: no
hard-coding of price and title allowed! This is also convenient for you
as you can change the price of your items knowing that it'll be reflected instantly
on your clients' devices.
Expand All @@ -80,9 +80,9 @@ Let's demonstrate this with an example:
render();
store.when("cc.fovea.test1").updated(render);
}

function render() {

// Get the product from the pool.
var product = store.get("cc.fovea.test1");

Expand All @@ -102,21 +102,21 @@ Let's demonstrate this with an example:
+ "<div class=\"description\">" + product.description + "</div>"
+ "<div class=\"price\">" + product.price + "</div>"
);

// Is this product owned? Give him a special class.
if (product.owned)
$el.addClass("owned");
else
$el.removeClass("owned");

// Is an order for this product in progress? Can't be ordered right now?
if (product.canPurchase)
$el.addClass("can-purchase");
else
$el.removeClass("can-purchase");
}
}

// method called when the view is hidden
function hide() {
// stop monitoring the product
Expand Down Expand Up @@ -387,7 +387,7 @@ A Promise with the following methods:
- `error(function(err){})`
- validation failed, either because of expiry or communication
failure.
- `err` is a [store.Error object](#errors), with a code expected to be
- `err` is a [store.Error object](#errors), with a code expected to be
`store.ERR_PAYMENT_EXPIRED` or `store.ERR_VERIFICATION_FAILED`.


Expand Down Expand Up @@ -415,7 +415,7 @@ Find below a diagram of the different states a product can pass by.
- `REQUESTED`: order (purchase) requested by the user
- `INITIATED`: order transmitted to the server
- `APPROVED`: purchase approved by server
- `FINISHED`: purchase delivered by the app
- `FINISHED`: purchase delivered by the app (see [Finish a Purchase](#finish-a-purchase))
- `OWNED`: purchase is owned (only for non-consumable and subscriptions)

#### Notes
Expand Down Expand Up @@ -904,7 +904,7 @@ Only supports JSON requests.

Options:

* `url`:
* `url`:
* `method`: HTTP method to use (GET, POST, ...)
* `success`: callback(data)
* `error`: callback(statusCode, statusText)
Expand Down
101 changes: 100 additions & 1 deletion doc/contributor-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
The implementation of the unified API is a small layer
built on top of the legacy "PhoneGap-InAppPurchase-iOS" plugin.

This was first decided as a temporary "get-things"done" solution.
This was first decided as a temporary "get-things-done" solution.
However, I found this ended-up providing a nice separation of concerns:

- the `platforms/ios-bridge.js` file exposes an API called `storekit` that matches the
Expand All @@ -22,3 +22,102 @@ However, I found this ended-up providing a nice separation of concerns:
- It reacts to product's changes of state, so that a product get's purchased
when `REQUESTED`, or finished when `FINISHED` for instance.

## Reacting to product state changes

The iOS implementation monitors products changes of state to trigger
`storekit` operations.

Please refer to the [product life-cycle section](api.md#life-cycle) of the documentation
for better understanding of the job of this event handlers.
#### initialize storekit
At first refresh, initialize the storekit API. See [`storekitInit()`](#storekitInit) for details.

#### initiate a purchase

When a product enters the store.REQUESTED state, initiate a purchase with `storekit`.

#### finish a purchase
When a product enters the store.FINISHED state, `finish()` the storekit transaction.

#### persist ownership

`storekit` doesn't provide a way to know which products have been purchases.
That is why we have to handle that ourselves, by storing the `OWNED` status of a product.

Note that, until Apple provides a mean to get notified to refunds, there's no way back.
A non-consumable product, once `OWNED` always will be.

http://stackoverflow.com/questions/6429186/can-we-check-if-a-users-in-app-purchase-has-been-refunded-by-apple


## Initialization

### <a name="storekitInit"></a> *storekitInit()*

This funciton will initialize the storekit API.

This initiates a chain reaction including [`storekitReady()`](#storekitReady) and [`storekitLoaded()`](#storekitLoaded)
that will make sure products are loaded from server, set as `VALID` or `INVALID`, and eventually restored
to their proper `OWNED` status.

It also registers the `storekit` callbacks to get notified of events from the StoreKit API:

- [`storekitPurchasing()`](#storekitPurchasing)
- [`storekitPurchased()`](#storekitPurchased)
- [`storekitError()`](#storekitError)


## *storekit* events handlers

### <a name="storekitReady"></a> *storekitReady()*

Called when `storekit` has been initialized successfully.

Loads all registered products, triggers `storekitLoaded()` when done.

### <a name="storekitLoaded"></a> *storekitLoaded()*

Update the `store`'s product definitions when they have been loaded.

1. Set the products state to `VALID` or `INVALID`
2. Trigger the "loaded" event
3. Set the products state to `OWNED` (if it is so)
4. Set the store status to "ready".

Note: the execution of "ready" is deferred to make sure state
changes have been processed.
### <a name="storekitPurchasing"></a> *storekitPurchasing()*

Called by `storekit` when a purchase is in progress.

It will set the product state to `INITIATED`.

### <a name="storekitPurchased"></a> *storekitPurchased()*

Called by `storekit` when a purchase have been approved.

It will set the product state to `APPROVED` and associates the product
with the order's transaction identifier.

### <a name="storekitError"></a> *storekitError()*

Called by `storekit` when an error happens in the storekit API.

Will convert storekit errors to a [`store.Error`](api.md/#errors).


## Persistance of the *OWNED* status

#### *isOwned(productId)*
return true iff the product with given ID has been purchased and finished
during this or a previous execution of the application.
#### *setOwned(productId, value)*
store the boolean OWNED status of a given product.

## Retry failed requests
When setup and/or load failed, the plugin will retry over and over till it can connect
to the store.

However, to be nice with the battery, it'll double the retry timeout each time.

Special case, when the device goes online, it'll trigger all retry callback in the queue.
2 changes: 1 addition & 1 deletion git_modules/android_iap
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cordova-purchase-plugin",
"version": "3.5.0-dev",
"description": "Cordova Purchase plugin for Apple AppStore for iOS and Google Play Store for Android",
"version": "3.9.1",
"description": "Cordova Purchase plugin for iOS and Android (AppStore and PlayStore)",
"repository": {
"type": "git",
"url": "https://github.com/j3k0/PhoneGap-InAppPurchase-iOS.git"
Expand All @@ -28,6 +28,7 @@
"homepage": "https://github.com/j3k0/PhoneGap-InAppPurchase-iOS",
"devDependencies": {
"cordova": "^3.6.3-0.2.13",
"eslint": "^0.9.1",
"istanbul": "^0.3.2",
"jshint": "^2.5.6",
"mocha": "^1.21.4",
Expand Down
18 changes: 9 additions & 9 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@
xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="cc.fovea.cordova.purchase"
version="3.9.0-beta.1">
version="3.9.1">

<name>Purchase</name>
<description>Cordova Purchase plugin for Apple AppStore for iOS and Google Play Store for Android</description>
<description>Cordova Purchase plugin for iOS and Android (AppStore and PlayStore)</description>
<engines>
<engine name="cordova" version=">=2.4.0" />
</engines>
<repo>https://github.com/j3k0/PhoneGap-InAppPurchase-iOS.git</repo>
<issue>https://github.com/j3k0/PhoneGap-InAppPurchase-iOS/issues</issue>
<repo>https://github.com/j3k0/cordova-plugin-purchase.git</repo>
<issue>https://github.com/j3k0/cordova-plugin-purchase/issues</issue>

<license>MIT</license>
<keywords>cordova,phonegap,purchase,storekit,ios,android,play,appstore</keywords>

Expand All @@ -21,10 +21,10 @@
<js-module src="www/store-ios.js" name="InAppPurchase">
<clobbers target="store" />
</js-module>

<!-- Cordova 2.2 -->
<plugins-plist key="InAppPurchase" string="InAppPurchase" />

<!-- Cordova 2.5+ -->
<config-file target="config.xml" parent="/*">
<feature name="InAppPurchase">
Expand Down Expand Up @@ -53,11 +53,11 @@

<!-- Cordova >= 3.0.0 -->
<config-file target="res/xml/config.xml" parent="/*">
<feature name="InAppBillingPlugin">
<feature name="InAppBillingPlugin">
<param name="android-package" value="com.smartmobilesoftware.inappbilling.InAppBillingPlugin"/>
</feature>
</config-file>

<!-- In-app Billing Library -->
<source-file src="src/android/com/android/vending/billing/IInAppBillingService.aidl" target-dir="src/com/android/vending/billing" />

Expand Down
11 changes: 10 additions & 1 deletion src/ios/InAppPurchase.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
- (void) load: (CDVInvokedUrlCommand*)command;
- (void) purchase: (CDVInvokedUrlCommand*)command;
- (void) appStoreReceipt: (CDVInvokedUrlCommand*)command;
- (void) appStoreRefreshReceipt: (CDVInvokedUrlCommand*)command;

- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions;
- (void) paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error;
Expand All @@ -44,5 +45,13 @@

@property (nonatomic,retain) InAppPurchase* plugin;
@property (nonatomic,retain) CDVInvokedUrlCommand* command;

@end;

@interface RefreshReceiptDelegate : NSObject <SKRequestDelegate> {
InAppPurchase* plugin;
CDVInvokedUrlCommand* command;
}

@property (nonatomic,retain) InAppPurchase* plugin;
@property (nonatomic,retain) CDVInvokedUrlCommand* command;
@end
Loading

0 comments on commit c6d0474

Please sign in to comment.