Activating customers via API


#1

How do we enable customers to activate their account for sending funds? We created these customer accounts through the API. We did not find any developer samples to reactivate the account for sending money.

"source": { "href":"https://api-sandbox.dwolla.com/funding-sources/e5478164-f902-449c-869a-57b7827a257c" }, 
"destination": { "href":"https://api-sandbox.dwolla.com/funding-sources/669175eb-ee3f-44e9-94ed-60e1e4311995" } 
}, 

Account is displayed as verified (see screenshot). How do we add a balance to the customer’s account via API?


(Spencer Hunter) #2

@sunlightmedia, It looks like the source Customer account (and destination Customer) hasn’t yet completed the requirements which makes them eligible to send funds. In order for business Verified Customers to be eligible to send funds they must: 1) ensure that the overall legal entity Customer which includes the business and Controller of the business has completed the identity verification process successfully and that they have a verified status. 2) All applicable Beneficial Owners have been attached to the legal entity Customer and that those individual owners have completed the identity verification process and have a verified status. 3) The account admin (individual signing up for the account) has certified ownership which verifies that information submitted for the legal entity Customer is complete and accurate.

This process outlined above for creating this particular Customer type is explained in more depth in this developer guide: https://developers.dwolla.com/resources/business-verified-customer.html. I would definitely recommend reading through that guide thoroughly and reach out if you have any questions!


#3

Thanks, @spencer.

We were able to complete verification (no notifications of documents or other actions needs are displaying now). We used the sample documents on https://developers.dwolla.com/resources/testing.html

However, we are receiving an error message now we’re not quite clear on:

Also the below code is displayed error. What does it mean? Please advise.  
$target_url = 'https://api-sandbox.dwolla.com/beneficial-owners/12b0de91-1649-48f3-8c4d-3f6da1a4a78c/documents';
$file_name_with_full_path = realpath('Passport_card.jpg') ;
     
$post = array('documentType' => 'passport','file'=>'@'.$file_name_with_full_path);
 
  $ch = curl_init();
  $headers = array(
    'Content-type: multipart/form-data',
    'Authorization: Bearer '. $token,
    'Accept: application/vnd.dwolla.v1.hal+json',
);

  curl_setopt($ch, CURLOPT_URL,$target_url);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_POST,1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  $result = json_decode(curl_exec($ch));
   
 
  echo '<pre>'.print_r($result,true).'</pre>';
stdClass Object
(
    [code] => NotFound
    [message] => The requested resource was not found.
)

(Spencer Hunter) #4

HI @sunlightmedia, is the Id you’re POSTing to a Customer ID or a Beneficial Owner Id? Those are separate resources in the API and will have their own unique identifier.


#5

We used the customer ID. Below are the steps we took. Please let us know where we went wrong.

  1. Create LLC Business account

URL = https://api-sandbox.dwolla.com/customers/cc7c1e33-1fc7-4a2a-85ca-9058e6658668

  1. Create Beneficial owners

URL = https://api-sandbox.dwolla.com/beneficial-owners/33fd7053-ae6f-4656-a8fe-2436131a5e23

  1. Create bank account

  2. Micro deposit verified.

  3. All Account status’ are verified and No action needed

We have created a transaction and the amount is reflected in the Dwolla account

07%20AM

But Send Fees to Admin ( main merchant ) is not reflected:

'fees'=>[
  '_links'=> [
  'charge-to'=> [
  'href'=> 'https://api-sandbox.dwolla.com/funding-sources/bfbcaaf8-42ad-4137-a4b6-2e7f25e3b3cc'],
  ]
  'amount'=> [
  'value'=>0.5 ,'currency'=>"USD"
  ]
],

(Spencer Hunter) #6

@sunlightmedia, it looks like the only thing that you’ll want to update on your end is the charge-to href. This will want to be a pointer to the Customer URL that identifies the user account you wish to assume the fee. i.e.

'fees'=>[
  '_links'=> [
  'charge-to'=> [
  'href'=> 'https://api-sandbox.dwolla.com/customers/cc7c1e33-1fc7-4a2a-85ca-9058e6658668'],
  ]
  'amount'=> [
  'value'=>0.5 ,'currency'=>"USD"
  ]
]

#7

@spencer We have set the fees charge-to href with the seller’s customer url http://api-sandbox.dwolla.com/customers/cc7c1e33-1fc7-4a2a-85ca-9058e6658668. But it is not showing the fees for the transaction where the main transaction is displayed. There should be 2 transactions – one with $0.50 (Fees) and another with $95.00 (main), but here we can only see the main transaction. Admin fees are not displayed. Our client would like to earn a commission per each transaction. Is this possible?

18%20AM

{  
	"_links":{
		"source":{
			"href":"https://api-sandbox.dwolla.com/funding-sources/bfbcaaf8-42ad-4137-a4b6-2e7f25e3b3cc"
		},
		"destination":{
			"href":"https://api-sandbox.dwolla.com\funding-sources/669175eb-ee3f-44e9-94ed-60e1e4311995"
		}
	},
	"amount":{
		"currency":"USD",
		"value":0.95
	},
	"fees":{
		"_links":{
			"charge-to":{
				"href":"http://api-sandbox.dwolla.com/customers/cc7c1e33-1fc7-4a2a-85ca-9058e6658668"
            },
            "amount":{
            	"value":0.05,
            	"currency":"USD"
            }
        },
        "metadata":{
        	"paymentId":"KHTJ1SKFHP0",
        	"note":"payment for #KHTJ1SKFHP0"
        },
        "clearing":{
        	"destination":"next-available"
        },
        "correlationId":"f9barivgnku6pka18tbjgvv387"
}

(Spencer Hunter) #8

Hi @sunlightmedia, The intent of the facilitator fee as it exists today is for you as the application to collect a fee from a portion of the transaction that your app facilitates. In this scenario you are facilitating transactions between two different users. If user A sends $0.95 and is being charged a fee of $0.05 then they should see $1 debited from their bank account. When that $1 settles and is marked as processed in the Dwolla system, you as the application (facilitator) will receive $0.05 and the recipient will receive the remaining $0.95. We don’t currently support sending the fee to an account that is different than the Master account that is building the app to facilitate transactions between users.


#9

Hi @spencer we’re not entirely clearly on this. What would be in the charge-to href field in this case? We did not find any customer ID for the Master Account. The main payment was $1 and it should send 0.95 to seller and 0.5 to the master Dwolla account.

"_links":{
	"source":{
		"href":"THIS IS THE BUYER FUNDING SOURCE LINK"
	},
	"destination":{
		"href":"THIS IS THE SELLER'S FUNDING SOURCE LINK"
		}
	},
	"amount":{
		"currency":"USD",
		"value":0.95
	},
	"fees":{
		"_links":{
		"charge-to":{
			"href":"WHAT IS THE MASTER CUSTOMER LINK? OR HERE WILL BE SELLER FUNDING SOURCE OR SELLERS CUSTOMER LINK? OR BUYER CUSTOMER LINK/FUNDING SOURCE LINK"
		}
	},
	"amount":{
		"value":0.05,
		"currency":"USD"
		}
	},

(Spencer Hunter) #10

Hi @sunlightmedia, If the Buyer (source) is being charged the fee in the transaction then it’ll be a link to the Customer resource that represents that buyer. i.e. https://api-sandbox.dwolla.com/customers/cc7c1e33-1fc7-4a2a-85ca-9058e6658668

Here’s an example:

$transfer = $transfersApi->create([
  '_links' => [
    'source' => [
      'href' => 'https://api-sandbox.dwolla.com/funding-sources/c91d6516-1855-4d36-be7c-bc78cc7c52c3',
    ],
    'destination' => [
      'href' => 'https://api-sandbox.dwolla.com/funding-sources/ae245cd4-ee55-4d20-8bad-a24642c9473f'
    ]
  ],
  'amount' => [
    'currency' => 'USD',
    'value' => '22.00'
  ],
  'fees' => [
    [
     '_links' => [
           'charge-to'=>[
              'href'=> 'https://api-sandbox.dwolla.com/customers/089cd9b4-fb5a-449e-a90e-30ffd83bbb9b'
            ]
        ],
        'amount' => [
             'value' => '2.00', // fee
              'currency' => 'USD'
           ]
    ]]
]);

#11

@spencer Does that mean that the source href = buyer’s funding source, and destination href = seller’s funding source, and fees charged to href link will be buyer’s account link?. If so, that’s how we currently have it set up.

EG: Buyer purchased a $1 product, so $0.95 will be sent to the seller and $0.05 will be sent to the main admin.


(Spencer Hunter) #12

@sunlightmedia, Yep, that’s correct!


#13

@spencer One issue we’re having is that transactions are occurring, but the fees are not listed in the Dwolla account transaction list in the Merchant account. Only the seller transactions are visible.


(Spencer Hunter) #14

@sunlightmedia, The issue might be how you’re passing in the Fees request param. It’s an array of Fee Objects which looks something like this:

{
"_links": {
    "source": {
        "href": "https://api-sandbox.dwolla.com/funding-sources/{{VCRBalanceFundingSourceId}}"
    },
    "destination": {
        "href": "https://api-sandbox.dwolla.com/funding-sources/{{CRFundingSourceId}}"
    }
},
"amount": {
    "currency": "USD",
    "value": "42.00"
},
"metadata": {
    "foo": "bar"
},
"fees": [
    {  
       "_links":{  
          "charge-to":{  
             "href":"https://api-sandbox.dwolla.com/customers/{{CRCustomerId}}"
          }
       },
       "amount":{  
          "value":"2.00",
          "currency":"USD"
       }
    }
]    

}

Can you share some of your code where you’re specifying Fees to confirm these are being passed in properly? If they aren’t we’ll ignore them and create the transaction without fees.


#15

Hi @spencer, transaction without fees are working fine. We’ll just need to provide the admin merchant a commission of 5-10%. That’s why we’ve added fees. Below is some sample code:

include('../dwolla/vendor/autoload.php'); 
$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL,DWOLLA_POST_URL_TOKEN);  
	curl_setopt($curl, CURLOPT_FAILONERROR, true);
	curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	 
	 $postData = array(
	 	'client_id' => DWOLLA_CLIENT_ID,
	 	'client_secret' => DWOLLA_CLIENT_SECRET,
	 	'grant_type' => 'client_credentials'
	 );
	 curl_setopt($curl, CURLOPT_POST, true);
	 curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($postData));
	 curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/x-www-form-urlencoded' )); // send JSON and expect JSON
	 
	//// Timeout in seconds
	 curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 0);
	 curl_setopt($curl, CURLOPT_TIMEOUT, 60);
	//// Dont verify SSL certificate (eg. self-signed cert in testsystem)
	 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
	 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	 $output = curl_exec($curl);
	if ($output === FALSE) {
		echo 'An error has occurred: ' . curl_error($curl) . PHP_EOL;
	}
	else {
		$output = json_decode($output) ;
		
		$token = $output->access_token;
	}
	
	DwollaSwagger\Configuration::$access_token = $token;
	DwollaSwagger\Configuration::$debug = 1;
	$apiClient = new DwollaSwagger\ApiClient(DWOLLA_API_CLIENT); 
	
	$transfersApi = new DwollaSwagger\TransfersApi($apiClient);
	$transfer = $transfersApi->create([
	  '_links' => [
	    'source' => [
	      'href' => $general_func->get_field_value(TBL_PREFIX. "user", "dwallo_funding_source", "user_id", $user_id) // Buyer funding source
	    ],
	    'destination' => [
	      'href' => $general_func->get_field_value(TBL_PREFIX. "user", "dwallo_funding_source", "user_id", $seller_id) // Seller funding source

	    ]
	  ],
	  'amount' => [
	    'currency' => 'USD',
	    'value' => '0.95'
	  ],
	  'fees' =>[
		   
		    '_links' => [
		      'charge-to' => [
		      'href' => $general_func->get_field_value(TBL_PREFIX. "user", "dwallo_account", "user_id", $user_id) // Buyer account URl

		      ]
		      ],
		    'amount' => [
		      'value' => 0.05,
		      'currency' => "USD"
		    ]
		   
		],
	  'metadata' => [
	    'paymentId' => $invoice,
	    'note' => 'payment for #'.$invoice,
	  ],
	  'clearing' => [
	    'destination' => 'next-available'
	  ],
	  'correlationId' => session_id()
	]);

 echo '<pre>'.print_r($post,true).'</pre>';  

#16

Hi @spencer, just following up on this


(Spencer Hunter) #17

@sunlightmedia, it looks like your fees array is missing an extra set of brackets.

'fees' => [
[
 '_links' => [
       'charge-to'=>[
          'href'=> 'https://api-sandbox.dwolla.com/customers/089cd9b4-fb5a-449e-a90e-30ffd83bbb9b'
        ]
    ],
    'amount' => [
         'value' => '2.00', // commission
          'currency' => 'USD'
       ]
]]

#18

Thank you, @spencer – this is working now.

The only remaining issue we have is related to document uploads. We’ve tried to upload PDFs and JPEG files, but are receiving an error.

$target_url =  'https://api-sandbox.dwolla.com/customers/83a44d27-ddfa-4b72-8d80-d34546a46a78/documents';
  $file_name_with_full_path =  '/documents/sample.jpg' ;  
  $post = array('documentType' => 'passport','file'=>'@'.$file_name_with_full_path); 
  $ch = curl_init();
  $headers = array(
    'Content-type: multipart/form-data',
    'Authorization: Bearer '. $token,
    'Accept: application/vnd.dwolla.v1.hal+json',
); 
  curl_setopt($ch, CURLOPT_URL,$target_url);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_POST,1);
  curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

  $result = json_decode(curl_exec($ch));
   
 
  echo '<pre>'.print_r($result,true).'</pre>';

ERROR
stdClass Object
(
    [code] => ValidationError
    [message] => Validation error(s) present. See embedded errors list for more details.
    [_embedded] => stdClass Object
        (
            [errors] => Array
                (
                    [0] => stdClass Object
                        (
                            [code] => Invalid
                            [message] => Invalid file type.
                            [path] => /file
                            [_links] => stdClass Object
                                (
                                )

                        )

                )

        )

)

#19

Hi @spencer, just following up on this


(Shreya Thapa) #20

Hi @sunlightmedia!

The curl handle in this line of your code seems to be inconsistent with the ones above it. Perhaps try changing that to:

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

When you are specifying the path for the file you are trying to upload, using the PHP realpath() function is a good practice, as it returns the canonicalized absolute pathname.

Furthermore, @spencer recommends using Guzzle, an easy-to-use PHP HTTP client library which has a simple interface for POSTing requests. They have a very well documented manual here. There is an abundance of resources on the internet on how to upload files using Guzzle.

Please let us know if the error persists; we would be glad to help you resolve it!