{"action":"created","issue":{"url":"https://api.github.com/repos/OneGov/onegov.town/issues/147","repository_url":"https://api.github.com/repos/OneGov/onegov.town","labels_url":"https://api.github.com/repos/OneGov/onegov.town/issues/147/labels{/name}","comments_url":"https://api.github.com/repos/OneGov/onegov.town/issues/147/comments","events_url":"https://api.github.com/repos/OneGov/onegov.town/issues/147/events","html_url":"https://github.com/OneGov/onegov.town/issues/147","id":123874615,"number":147,"title":"Add Credit Card Payment","user":{"login":"freinhard","id":186856,"avatar_url":"https://avatars.githubusercontent.com/u/186856?v=3","gravatar_id":"","url":"https://api.github.com/users/freinhard","html_url":"https://github.com/freinhard","followers_url":"https://api.github.com/users/freinhard/followers","following_url":"https://api.github.com/users/freinhard/following{/other_user}","gists_url":"https://api.github.com/users/freinhard/gists{/gist_id}","starred_url":"https://api.github.com/users/freinhard/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/freinhard/subscriptions","organizations_url":"https://api.github.com/users/freinhard/orgs","repos_url":"https://api.github.com/users/freinhard/repos","events_url":"https://api.github.com/users/freinhard/events{/privacy}","received_events_url":"https://api.github.com/users/freinhard/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-12-25T11:24:10Z","updated_at":"2016-06-20T13:24:06Z","closed_at":null,"body":"A new field type in form definitions allows online payments. Use Stripe as payment gateway."},"comment":{"url":"https://api.github.com/repos/OneGov/onegov.town/issues/comments/227140627","html_url":"https://github.com/OneGov/onegov.town/issues/147#issuecomment-227140627","issue_url":"https://api.github.com/repos/OneGov/onegov.town/issues/147","id":227140627,"user":{"login":"href","id":273163,"avatar_url":"https://avatars.githubusercontent.com/u/273163?v=3","gravatar_id":"","url":"https://api.github.com/users/href","html_url":"https://github.com/href","followers_url":"https://api.github.com/users/href/followers","following_url":"https://api.github.com/users/href/following{/other_user}","gists_url":"https://api.github.com/users/href/gists{/gist_id}","starred_url":"https://api.github.com/users/href/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/href/subscriptions","organizations_url":"https://api.github.com/users/href/orgs","repos_url":"https://api.github.com/users/href/repos","events_url":"https://api.github.com/users/href/events{/privacy}","received_events_url":"https://api.github.com/users/href/received_events","type":"User","site_admin":false},"created_at":"2016-06-20T13:24:06Z","updated_at":"2016-06-20T13:24:06Z","body":"To implement this feature we have to look at a number of components.\r\n\r\n- Payment Provider\r\n- Prices\r\n- Charges/Refunds\r\n- Reporting\r\n\r\n# Payment Provider\r\n\r\nStripe is the obvious choice. Unfortunately they are still in private beta in Switzerland. That means our clients need to sign up with the beta and are not guaranteed entry. For what it's worth though, I signed up and got an invite 5 minutes later.\r\n\r\nFor integration we want to open a [Stripe Connect](https://stripe.com/connect) account, which allows us to connect with other Stripe accounts. Unfortunately it's not yet possible to use \"managed accounts\" in Switzerland, which would allow us completely hide Stripe from the user (they would essentially just enter their bank account number).\r\n\r\n## Fee\r\n\r\nStripe takes a fee from each payment. We can add to this fee if we want to through Stripe Connect.\r\n\r\n## VAT\r\n\r\nI'm not sure how the VAT(MwSt) is handled at the moment, but I assume that this is the town's problem. In any case, we need to work with towns in this regard to find out how they are doing this, because their calculations will have to change with the the added fee.\r\n\r\n## Including / Excluding Fees\r\n\r\nWe might also have to provide a way to add the MwSt on top of all payments. For example, the town might say that it needs 40.- for a daypass, so the citizen has to pay 41.50 for the town to actually receive 40.\r\n\r\nIt should be up to the town if they want to pay the fee themselves or if they want to pass that along to the citizens.\r\n\r\n# Prices\r\n\r\nTo charge anything to anyone we need to set prices. Those prices are ultimately associated with the ticket, but they are not derived from it.\r\n\r\nI see the following places where prices make sense:\r\n\r\n* Custom forms\r\n* Reservations\r\n\r\nTechnically we could also set prices for events (for publication). This should be kept as a possibility, but I don't want to actually develop it for now. It's not a likely feature, just a possible one.\r\n\r\n## Custom Forms Pricing\r\n\r\nCustom forms need the ability to set prices in a flexible way. Current forms have a number of options which influence the price. There are multiple items that can be ordered, different shipping options and so on.\r\n\r\nTherefore I suggest we integrate pricing into Formcode. This could be a possible syntax:\r\n\r\n```python\r\n# Personal Details\r\nProducts *=\r\n    [ ] Govikon history book (+10 CHF)\r\n    [ ] Govikon DVD (+15 CHF)\r\n\r\nDelivery *=\r\n    ( ) Pick up\r\n    ( ) to Swiss address (+5 CHF)\r\n    ( ) outside Switzerland (+15 CHF)\r\n```\r\n\r\nThis doesn't necessarily reflect the syntax we will use and we also might end up implementing this outside of Formcode. It's technically something that we could support without it (or through some kind of extension mechanism).\r\n\r\n## Reservations Pricing\r\n\r\nDaypasses are usually priced per pass and day. Rooms are more likely to have a single price per reservation. We should therefore:\r\n\r\n* Allow to set a price per allocation (reserved as a whole).\r\n* Allow to set a price per reservation on a calendar (that is for each date reserved).\r\n* Allow to set a price per ticket (that is for multiple reservations done in one step).\r\n\r\nThe price per allocation should be set on the allocation itself. The price of a reservation is set on the resource as such and the price per ticket is set through the form, just like custom forms.\r\n\r\n# Charges / Refunds\r\n\r\nWhen filling out the form before the ticket is sent, the citizen will enter their credit card information which is then stored with Stripe. Only once the reservation/custom form has been processed will he actually be billed.\r\n\r\nThis has a few consequences:\r\n\r\n* We need a workflow state or some other way to mark a ticket as paid.\r\n* We need to be explicit about when the card is charged.\r\n* It's possible that the card cannot be charged (in which case it is up to the employee to proceed or cancel).\r\n* It must be possible to refund a charge.\r\n\r\nA change in form data can lead to a change in the charge. This should not be possible. It should also not be possible to manipulate the charged amount. If there is any problem with the actual value, the form/reservation should be discarded and a new attempt should be made. This helps prevent disputes and errors.\r\n\r\nI suggest that custom forms get an \"accept and charge\" and a \"cancel\" option like reservations already do. This would make the change more explicit. In any case we will have to show a popup before the charge occurs.\r\n\r\nSince it's possible for charges to be disputed we should show a payment status with each ticket.\r\n\r\n## Workflow State / Paid Tickets\r\n\r\nThis has the added benefit of solving the problem that Rüti has with open tickets. We can be more specific about them in the future (they might still be open, but it would be clear why that is).\r\n\r\n## Charges without Credit Cards\r\n\r\nEven if a citizen offers no credit card we can use the added pricing information to show the bill that needs to be made. This way we can always inform the citizen and the government employee about the agreed upon costs.\r\n\r\n# Reporting\r\n\r\nWith the added pricing information we can show a price for each ticket and render a simple report that shows what amounts were paid, what amounts are open and if there are any disputes ore problems."}}
{"actor":{"display_login":"href"}}