kvs_payment.erl 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. -module(kvs_payment).
  2. -include_lib("kvs/include/kvs.hrl").
  3. -include_lib("kvs/include/membership.hrl").
  4. -include_lib("kvs/include/payments.hrl").
  5. -include_lib("kvs/include/accounts.hrl").
  6. -include_lib("kvs/include/feed_state.hrl").
  7. -compile(export_all).
  8. init(Backend) ->
  9. ?CREATE_TAB(payment),
  10. ?CREATE_TAB(user_payment),
  11. ok.
  12. payments(UserId) -> payments(UserId, undefined).
  13. payments(UserId, PageAmount) ->
  14. case kvs:get(user_payment, UserId) of
  15. {ok, O} -> kvs:entries(O, payment, PageAmount);
  16. {error, _} -> [] end.
  17. payments(UserId, StartFrom, Limit) ->
  18. case kvs:get(payment, StartFrom) of
  19. {ok, P} -> kvs:traversal(payment, P, Limit);
  20. X -> [] end.
  21. user_paid(UId) ->
  22. case kvs:get(user_payment, UId) of
  23. {error,_} -> false;
  24. {ok,#user_payment{top = undefined}} -> false;
  25. _ -> true end.
  26. default_if_undefined(Value, Undefined, Default) ->
  27. case Value of
  28. Undefined -> Default;
  29. _ -> Value end.
  30. charge_user_account(_MP) -> ok.
  31. % OrderId = MP#payment.id,
  32. % Package = MP#payment.membership,
  33. % UserId = MP#payment.user_id,
  34. %
  35. % Currency = Package#membership.currency,
  36. % Quota = Package#membership.quota,
  37. %
  38. % PaymentTransactionInfo = #tx_payment{id=MP#payment.id},
  39. %
  40. % try
  41. % kvs_account:transaction(UserId, currency, Currency, PaymentTransactionInfo),
  42. % kvs_account:transaction(UserId, quota, Quota, PaymentTransactionInfo)
  43. % catch
  44. % _:E ->
  45. % error_logger:info_msg("unable to charge user account. User=~p, OrderId=~p. Error: ~p",
  46. % [UserId, OrderId, E])
  47. % end.
  48. add_payment(#payment{} = MP) -> add_payment(#payment{} = MP, undefined, undefined).
  49. add_payment(#payment{} = MP, State0, Info) ->
  50. error_logger:info_msg("ADD PAYMENT"),
  51. Start = now(),
  52. State = default_if_undefined(State0, undefined, ?MP_STATE_ADDED),
  53. StateLog = case Info of
  54. undefined -> [#state_change{time = Start, state = State, info = system_change}];
  55. _ -> [#state_change{time = Start, state = State, info = Info}] end,
  56. Id = default_if_undefined(MP#payment.id, undefined, payment_id()),
  57. kvs:add(MP#payment{id = Id, state = State, start_time = Start, state_log = StateLog, feed_id=MP#payment.user_id}).
  58. set_payment_state(MPId, NewState, Info) ->
  59. case kvs:get(payment, MPId) of
  60. {ok, MP} ->
  61. Time = now(),
  62. StateLog = MP#payment.state_log,
  63. NewStateLog = [#state_change{time = Time, state = NewState, info = Info}|StateLog],
  64. EndTime = case NewState of
  65. ?MP_STATE_DONE -> now();
  66. ?MP_STATE_CANCELLED -> now();
  67. ?MP_STATE_FAILED -> now();
  68. _ -> MP#payment.end_time
  69. end,
  70. Purchase = MP#payment{state = NewState, end_time = EndTime, state_log = NewStateLog},
  71. mqs:notify([kvs_payment,user,Purchase#payment.user_id,notify],Purchase),
  72. NewMP=MP#payment{state = NewState, end_time = EndTime, state_log = NewStateLog},
  73. kvs:put(NewMP),
  74. if
  75. NewState == ?MP_STATE_DONE -> charge_user_account(MP); % affiliates:purchase_hook(NewMP);
  76. true -> ok
  77. end,
  78. ok;
  79. Error -> error_logger:info_msg("Can't set purchase state, not yet in db"), Error
  80. end.
  81. set_payment_info(MPId, Info) ->
  82. {ok, MP} = kvs:get(payment, MPId),
  83. kvs:put(MP#payment{info = Info}).
  84. set_payment_external_id(MPId, ExternalId) ->
  85. {ok, MP} = kvs:get(payment, MPId),
  86. case MP#payment.external_id of
  87. ExternalId -> ok;
  88. _ -> kvs:put(MP#payment{external_id = ExternalId}) end.
  89. list_payments() -> kvs:all(payment).
  90. list_payments(SelectOptions) ->
  91. Predicate = fun(MP = #payment{}) -> kvs_membership:check_conditions(SelectOptions, MP, true) end,
  92. kvs_membership:select(payment, Predicate).
  93. payment_id() ->
  94. NextId = kvs:next_id("payment"),
  95. lists:concat([timestamp(), "_", NextId]).
  96. handle_notice([kvs_payment, user, Owner, set_state] = Route,
  97. Message, #state{owner = Owner, type =Type} = State) ->
  98. error_logger:info_msg("queue_action(~p): set_purchase_state: Owner=~p, Route=~p, Message=~p", [self(), {Type, Owner}, Route, Message]),
  99. {MPId, NewState, Info} = Message,
  100. set_payment_state(MPId, NewState, Info),
  101. {noreply, State};
  102. handle_notice([kvs_payment, user, Owner, add] = Route,
  103. Message, #state{owner = Owner, type =Type} = State) ->
  104. error_logger:info_msg("queue_action(~p): add_purchase: Owner=~p, Route=~p, Message=~p", [self(), {Type, Owner}, Route, Message]),
  105. {MP} = Message,
  106. error_logger:info_msg("Add payment: ~p", [MP]),
  107. add_payment(MP),
  108. {noreply, State};
  109. handle_notice(["kvs_payment", "user", _, "set_external_id"] = Route,
  110. Message, #state{owner = Owner, type =Type} = State) ->
  111. error_logger:info_msg("queue_action(~p): set_purchase_external_id: Owner=~p, Route=~p, Message=~p", [self(), {Type, Owner}, Route, Message]),
  112. {PurchaseId, TxnId} = Message,
  113. set_payment_external_id(PurchaseId, TxnId),
  114. {noreply, State};
  115. handle_notice(["kvs_payment", "user", _, "set_info"] = Route,
  116. Message, #state{owner = Owner, type =Type} = State) ->
  117. error_logger:info_msg("queue_action(~p): set_purchase_info: Owner=~p, Route=~p, Message=~p", [self(), {Type, Owner}, Route, Message]),
  118. {OrderId, Info} = Message,
  119. set_payment_info(OrderId, Info),
  120. {noreply, State};
  121. handle_notice(Route, _, State) ->
  122. %error_logger:info_msg("Unknown PAYMENTS notice ~p for: ~p, ~p", [Route, State#state.owner, State#state.type]),
  123. {noreply, State}.
  124. timestamp()->
  125. {Y, Mn, D} = erlang:date(),
  126. {H, M, S} = erlang:time(),
  127. lists:flatten(io_lib:format("~b~2..0b~2..0b_~2..0b~2..0b~2..0b", [Y, Mn, D, H, M, S])).