Skip to content

Commit

Permalink
added start of a recipes section
Browse files Browse the repository at this point in the history
  • Loading branch information
pelle committed Jan 11, 2012
1 parent 91a3abc commit 94b0b86
Show file tree
Hide file tree
Showing 5 changed files with 605 additions and 1 deletion.
1 change: 1 addition & 0 deletions _layouts/default.html
Expand Up @@ -24,6 +24,7 @@
<ul class="nav">
<li><a href="/">Home</a></li>
<li><a href="/usecases.html">Use cases</a></li>
<li><a href="/recipes/">Recipes</a></li>
<li><a href="/core.html">Spec</a></li>
<li><a href="/videos.html">Videos</a></li>
<li>
Expand Down
3 changes: 2 additions & 1 deletion index.html
@@ -1,5 +1,5 @@
---
title:
title: the worlds simplest spec for financial transactions
layout: default
---
<div class="hero-unit">
Expand Down Expand Up @@ -76,6 +76,7 @@ <h5>Use cases:</h5>
<ul>
<li>Advanced shopping carts</li>
<li>Exchanges</li>
<li><a href="/recipes/crowdfunding.html">Crowd Funding services</a></li>
</ul>
<p>
Some simple web programming skills are necessary. See the <a href="/core.html#transfer-authorization-1" title="Transfer Authorization Spec">spec</a> for more details.
Expand Down
319 changes: 319 additions & 0 deletions recipes/crowdfunding.md
@@ -0,0 +1,319 @@
---
title: Crowdfunding
layout: default
---

# Crowdfunding

Crowdfunding is when a group of people pool their money together to fund a project. The most popular example right now is [Kickstarter](http://kickstarter.com).

<div class="thumbnail"><a href="http://www.kickstarter.com/projects/1202515667/the-city-troll-a-graphic-novel?ref=spotlight"><img src="https://img.skitch.com/20120111-2tc6mnte63qr52sahpu1xsbqk.preview.jpg" alt="A KickStarter project" /></a></div>

To avoid fraud and ensure the success of the project a popular implementation rule is to have a minimum funding goal and an expiration date on the project.

Eg. Project X is looking for minimum $10,000 within the next month.

A crowdfunding service such as [Kickstarter](http://kickstarter.com) would handle most of the business logic surrounding crowdfunding.

They can integrate with existing OpenTransact providers for the funding part as well as present an OpenTransact interface for each project as well.

We will handle both cases here:

- [The Crowd Funding service using OpenTransact as a Client](#client)
- [The Crowd Funding service as the OpenTransact provider](#provider)

## Roles

- Offerer - The person/organization listing a project for funding (Alice)
- Supporter - The person wanting to help fund project (Bob)
- Crowdfunding Service - The service provider (CrowdStarter)
- Payment Provider - The payment provider used (PayMe)

## <span id="client">Integrate with OpenTransact payment provider</span>

1. Alice registers her project on Crowdstarter site and decides she needs $10,000
2. CrowdStarter approves the project and sets an expiration date 2 months in the future
3. Bob views Alice's project on CrowdStarter's site.
4. <span id="pledge">Bob clicks the Pledge button and enters an amount ($20) he wants to pledge.</span>
5. The Crowdfunding site generates an [OpenTransact Transfer Authorization](/core.html#transfer-authorization-1) link to Bob's payment provider PayMe.
6. Bob clicks the link and goes to PayMe
7. PayMe asks Bob if he wants to approve the request for $20 valid until 2 months in the future.
8. Bob approves and gets redirected back to CrowdStarter with an [OAuth2.0 authorization code](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1.2).
9. CrowdStarter exchanges the authorization code with a [OAuth 2.0 access token request](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1.3) and stores the resulting token in their database

Now 2 things can happen:

### Project meets it's funding goal

Cool everyone is happy.

CrowdStarter finds all successful pledges to the project and goes through each one performing the following:

1. CrowdStarter performs an [OpenTransact Transfer](http://www.opentransact.org/core.html#transfer-1) with the Access Token from Step. 9 above
2. CrowdStarter funds using to Alice's account at PayMe again using an [OpenTransact Transfer](http://www.opentransact.org/core.html#transfer-1) but this time with their own Access Token

### Project did not meet it's funding goal

The Access Token received earlier should expire shortly after the date the fundraising session expired, so CrowdStarter doesn't really have to do anything.

However we think it is best practise to explicitly revoke the token using the [OAuth 2.0 Token revocation spec](http://tools.ietf.org/html/draft-lodderstedt-oauth-revocation-03)


### Detailed examination of steps

It helps to see how this actually is implemented. So here we show it using raw HTTP posts. We will create examples in Ruby and other languages later.

#### <span id="transfer_authorization">Transfer Authorization</span>

The Transfer Authorization link in Step 5. is built up with the following parameters:

- amount=20.00 # The amount to authorize
- to=alice@project.example.com # Alice's email address
- for=http://crowdstarter.example.com/projects/123123 # The URL to the project
- validity=P34D # The authorization should be valid for 34 days from now [see](http://www.opentransact.org/core.html#validity-duration)
- client_id=1234134 # The preregistered OAuth client id of CloudStarter on PayMe
- response_type=code # code or token [see](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-1.3)
- redirect_uri=http://crowdstarter.example.com/projects/12313/thanks
- state=123455 # A Unique value used by CrowdStarter to identify the user

These parameters are URL form encoded and appended as a query string to PayMe's OpenTransact URL:

https://payme.example.com/usd?amount=20&for=http://crowdstarter.example.com/projects/123123&validity=P34D&client_id=1234134&response_type=code&redirect_uri=http://crowdstarter.example.com/projects/12313/thanks&state=123455


#### Fetch Access Token

Once Bob has authorized the transfer and is redirected back to the CrowdStarter site in step 8 he receives the following parameters in the query string [see](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1.2):

- code=4a94c45bc356bcebf76f2d7d2ce435b5 # a unique access code generated by PayMe
- state=123455 # the state variable sent a long before

CrowdStarter now performs an [OAuth 2.0 Token Request](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.1.3) to get the AccessToken they will use later.

POST /token HTTP/1.1
Host: payme.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded;charset=UTF-8

grant_type=authorization_code&code=4a94c45bc356bcebf76f2d7d2ce435b5&redirect_uri=http://crowdstarter.example.com/projects/12313/thanks

PayMe returns an Access Token as JSON:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":2937600
}

Note that it includes the expires_in parameter which should contain the requested validity duration in seconds.

#### Perform OpenTransact Transfer

Once the payment goal is achieved CrowdStarter performs individual transfers like this.

POST /usd HTTP/1.1
Host: payme.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Content-length: 0


It uses the access token as received above and sends an empty body. PayMe knows the amount and recipient so no need to specify anything else.

## <span id="provider">The Crowd Fund service as an OpenTransact provider</span>

[Assets](http://www.opentransact.org/core.html#assets) are the most important thing to understand about OpenTransact.

A payment providers service for USD is one example of an asset. Stock in Google is another. Each asset has a unique [Transaction URL](http://www.opentransact.org/core.html#transaction-url) which accepts the various OpenTransact requests.

For a Crowd Funding service like CrowdStarter each project is an asset.

As in each $1 unit in the asset means that I am pledging $1 to support the project.

So lets assume Alice's project's URL is:

http://crowdstarter.example.com/projects/123123

This is the url which would contain the exact same information on the page as it does today.

So what would enabling OpenTransact on this URL allow people to do?

- Alice could promote specific links (Transfer Requests) in her social network
- Crowd Funding aggregators could be built finding the best projects around the web
- Crowd Funding mobile apps could be easily created supporting multiple providers

So the main two requirements of this is to be able to

- Request a Pledge from another web app/twitter/email
- Perform a Pledge via a third party app

### Listing projects

A simple way for projects to be listed would be to use the [Atom Syndication Format](http://tools.ietf.org/html/rfc4287). Each Crowd Funding service could list their projects with photos/descriptions/media etc.

The item url would be the above OpenTransact URL making it easy for both web apps and mobile apps to learn about the projects and integrate with them.

### OpenTransact Request

[OpenTransact](/) consists of 3 types of requests:

- [Transfer Request](http://www.opentransact.org/core.html#transfer-request)
- [Transfer Authorization](http://www.opentransact.org/core.html#transfer-authorization)
- [Transfer](http://www.opentransact.org/core.html#transfer)

The Transfer Request is used in payment buttons, email links and anywhere you would request that a user pledges to support the project.

Transfer Authorization is a bit more complicated to implement. It requests the same transfer as the Transfer Request but instead of performing it, it issues OAuth 2 credentials to allow the service to perform the transfer later. I can't quite think of a use case where this would be useful for a Crowd Funding service.

The Transfer it self is used by an external app such as a mobile phone app to pledge to support a project.

### Transfer Request

The [OpenTransact parameters](http://www.opentransact.org/core.html#transfer-request-1) relevant to CrowdFunding could be:

- *to* The person making the pledge (see below)
- *amount* The amount I want to pledge
- *note* Textual description, which can include hash tags. Crowd Funding service may truncate this. No default.
- *for* URI relating pledge with some other item
- *redirect_uri* URI for redirecting client to afterwards
- *callback_uri* URI for performing a web callback

All of these are optional and user is just presented with a bare pledge form if left out.

#### Who is the recipient

'to' is interesting and presents us with a couple of semantic issues we need to think about.

When you first look at it you might think that to should be the recipient of the pledge (Alice). But really the beneficiary of all pledges within this project is Alice so the Supporter (Bob) is actually buying a "Pledge" asset to his own name. He could also pledge and pay on behalf of someone else, similar to the popular send money in your name to charity X christmas cards.

#### Examples

A perfectly valid Transfer Request would be sending the user to the OpenTransact url without query parameters.

http://crowdstarter.example.com/projects/123123

You could think of a scenario where a local school asks people to support a project on their behalf.

http://crowdstarter.example.com/projects/123123?to=fundraising@elmhurst-elementary.sample.edu

A Crowd funding aggregator might want to link people to projects and hear back from the crowd funding aggregator to create popularity statistics.

http://crowdstarter.example.com/projects/123123?callback_uri=http://crowdedlist.sample.com/callback

Through these simple parameters many different mashups could be created to help people fundraise their projects.

#### Implementation

If none of the OpenTransact parameters are present the crowd funding service should just present their regular interface.

If any of the OpenTransact parameters are present the service fills out relevant parts of their interface and continues in [step 4](#pledge) above.

If a *redirect_uri* or *callback_uri* was present the Crowd funding service redirects the user back to the given redirect_uri and/or posts the receipt to the given callback_uri.

### Transfer

To allow transfers the Crowd Funding service needs to have an OAuth 2.0 implementation. There are implementations for just about any language now and this is in itself fairly straight forward.

Any application mobile or otherwise needs to register as a Client with the Crowd Funding service. They can then obtain and [authorize an OAuth Access token](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4). This used to be quite complex for mobile apps, but the new [Password Credentials authorization](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.3) is pretty straightforward from a usability standpoint.

In our case the user already has an account with the crowd funding service and has already linked their account with an OpenTransact payment provider using OAuth.

Lets assume the App already has a token "23d1760359159578aed0437e400f3b36" authorized by Bob.

- Bob browses the latest projects on his mobile crowd funding app and find Alice's project.
- He decides to support the project and pledge $20.
- The mobile app sends an OpenTransact Transfer of $20 to the OpenTransact url of the project
- CrowdStarter receives the request and verifies who is the user related to the OAuth token
- CrowdStarter reserves $20 at PayMe [Learn more about reserves](reserves.html)
- CrowdStarter creates a pledge in their database
- CrowdStarter returns a receipt to the mobile app


#### Implementation

The app sends the following to crowdstarter:

POST /projects/123123 HTTP/1.1
Host: crowdstarter.example.com
Authorization: Bearer 23d1760359159578aed0437e400f3b36
Content-length: 9

amount=20

CrowdStarter creates an initial Pledge in their system and sends the following to PayMe:

POST /usd/reserves HTTP/1.1
Host: payme.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
Content-length: 105

amount=20&for=https://crowdstarter.example.com/pledges/1231245&to=alice@project.example.com&validity=P34D

PayMe reserves $20 and returns the following:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
"txn_url":"https://payme.example.com/reserves/1231245",
"to": "alice@project.example.com",
"from": "bob@project.example.com",
"asset_url":"https://payme.example.com/usd",
"amount":20,
"expires_in":2937600,
"for":"https://crowdstarter.example.com/pledges/1231245",
"timestamp":"2012-01-11 22:08:48 UTC"
}

CrowdStarter marks the pledge as valid and returns the following to the App:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
"txn_url":"https://crowdstarter.example.com/pledges/1231245",
"asset_url":"http://crowdstarter.example.com/projects/123123",
"from": "alice@project.example.com",
"to": "bob@project.example.com",
"asset_url":"https://payme.example.com/usd",
"amount":20,
"expires_in":2937600,
"for":"https://payme.example.com/transactions/1231245",
"timestamp":"2012-01-11 22:08:48 UTC"
}

That is the full flow and is a good example of a chained OpenTransact exchange transaction.

#### What happens if the user hasn't authorized payment?

This is a proposed pattern that we may bring into the standard.

If a transfer can not be done due to lack of balance. The HTTP standard defines [status code 402](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error) which could be used with a Location header field.

The user can then be redirected to that url to connect to a payment mechanism.

In practice CrowdStarter could return the OpenTransact url with the same OpenTransact parameters as in the Transfer

http://crowdstarter.example.com/projects/123123?amount=20

They could return the following:

HTTP/1.1 402 OK
Location: http://crowdstarter.example.com/projects/123123?amount=20
Cache-Control: no-store
Pragma: no-cache

The mobile app can then open a web browser with the link and append a redirect_uri to their application:

http://crowdstarter.example.com/projects/123123?amount=20&redirect_uri=com.sample.myapp:project

Once the user has authorized the payment in their mobile browser they get redirected back to the app.

33 changes: 33 additions & 0 deletions recipes/index.md
@@ -0,0 +1,33 @@
---
title: Recipes
layout: default
---

# OpenTransact Recipes

How to implement common use cases in OpenTransact.

A common question of OpenTransact since it is very simple is how it can be used to implement more complex applications.

The goal of these specs is to build up best practices. Please feel free to add new ones to the [wiki](https://github.com/opentransact/opentransact/wiki) or [fork us](https://github.com/opentransact/opentransact.github.com) and create new ones or changes.

The end result of these may become further smaller standards.

## CrowdFunding

Crowdfunding is when a group of people pool their money together to fund a project.

[See how to implement Crowd funding with OpenTransact](crowdfunding.html)

## Reserves

Reserves are a way of reserving or holding funds in another OpenTransact asset.

[See how to implement Reserves with OpenTransact](reserves.html)

## Exchanges

How to use OpenTransact to exchange one asset for another.

TBD

0 comments on commit 94b0b86

Please sign in to comment.